読者です 読者をやめる 読者になる 読者になる

Djangoroidの奮闘記

python,django,angularJS1~三十路過ぎたプログラマーの奮闘記

Django e-commerce part60 Model Choice Field

Model Choice Fieldを利用してみる

公式ドキュメント:

Form fields | Django documentation | Django

orders/froms.py のAddressFormに追記してみる。

from .models import UserAddress
...
class AddressForm(forms.Form):
    billing_address = forms.ModelChoiceField(queryset=UserAddress.objects.all(),)
    shipping_address = forms.ModelChoiceField(queryset=UserAddress.objects.all(),)

さらに、上記に、アドレスの種類でフィルターをかけてみる。

class AddressForm(forms.Form):
    billing_address = forms.ModelChoiceField(queryset=UserAddress.objects.filter(type="billing"))
    shipping_address = forms.ModelChoiceField(queryset=UserAddress.objects.filter(type="shipping"))

さらに、empty の---- という選択をなくす

class AddressForm(forms.Form):
    billing_address = forms.ModelChoiceField(
            queryset=UserAddress.objects.filter(type="billing"),
            empty_label = None,
            )
    shipping_address = forms.ModelChoiceField(
            queryset=UserAddress.objects.filter(type="shipping"),
            empty_label = None,            
            )

orders/views.py に追記する。

class AddressSelectFormView(FormView):
    form_class = AddressForm
    template_name = "orders/address_select.html"

    def get_form(self, *args, **kwargs):
        form = super(AddressSelectFormView, self).get_form(*args, **kwargs)
        form.fields["billing_address"].queryset = UserAddress.objects.filter(
                user__email=self.request.user.email,
                type='billing',
                )
        form.fields["shipping_address"].queryset = UserAddress.objects.filter(
                user__email=self.request.user.email,
                type='shipping',
                )
        return form

ポイント

  • FormView の、get_form メソッドを上書きしている。これにより、viewsを読み込んだ時は、get_formでゲットしたフォームを表示するようになる。
  • さらに、form のfieldsのquerysetに、useremailと、typeで、filterしたquerysetを代入する。
  • 最後に返すのは、get_formなので、form

from_valid を上書きする。

class AddressSelectFormView(FormView):
...
    def form_valid(self, *args, **kwargs):
        form = super(AddressSelectFormView, self).form_valid(*args, **kwargs)
        print form
        return form

form_validは、postされた時に、実行されるはず。

ordrs/address_selector.html を編集する。

form postをつける

{% extends "base.html" %}
{% load crispy_forms_tags %}

{% block content %}

<form method="POST" action=''>{% csrf_token %}
{{ form|crispy }}
<input type='submit' value='選択する'>
</form>
{% endblock %}

このままだと、get_success_urlの指定がないというerrorが出る。

view.pyにget_success_urlを追記する。

    def get_success_url(self, *args, **kwargs):
        return "/checkout"

疑問点

  • get_success_url はmodelFormなどだと自動的に設定されているのか??