Django фильтрует набор запросов ModelChoiceField, используя URL-адрес для заполнения формы - PullRequest
0 голосов
/ 29 марта 2020

Я уверен, что это либо простое исправление, либо я что-то неправильно понял.

В этом приложении магазины - это «продукты», и для каждого магазина есть несколько вариантов Облигаций.

По сути, желаемое поведение:

  1. Пользователь направлен на website.com/stores/store-slug
  2. Фильтр для соответствующего магазина Store.objects.filter(anchor=store_slug)
  3. Выбор формы заполняется Bonds.objects.filter(store=store)

Я хочу заполнить варианты ListingForm связями, связанными с этим магазином. Может ли кто-нибудь помочь мне добиться этого должным образом?

urls.py

urlpatterns = [
    path('', views.HomeView.as_view(), name='home'),
    path('stores/<slug:anchor>', views.ListingView.as_view(), name='listing'),
]

forms.py

from django import forms
from store.models import Bond

class ListingForm(forms.Form):
    face_value = forms.ModelChoiceField(queryset=...) # this part is a problem

    def __init__(self, store, *args, **kwargs):
        super(ListingForm, self).__init__(*args, **kwargs)
        self.fields['face_value'].queryset = Bond.objects.filter(store=store)

view.py

class ListingView(FormView):
    template_name = 'listing.html'
    form_class = ListingForm
    success_url = '/checkout/preview' # todo

    anchor = None # this feels wrong...
    store = None
    queryset = None

    def get_form_kwargs(self):
        kwargs = super(ListingView, self).get_form_kwargs()
        kwargs['store'] = self.store

    def get_context_data(self, **kwargs):
        self.anchor = self.kwargs.get('anchor')
        self.store = Store.objects.filter(anchor_id=self.anchor).first()
        self.queryset = Bond.objects.filter(store=self.store)

        context = super(FormView, self).get_context_data(**kwargs)

        context['store'] = self.store
        context['store_bonds'] = self.queryset
        return context

    def form_valid(self, form):
        # save selected bond to session
        # redirect to success_url
        face_value = form.cleaned_data['face_value']
        bond = Bond.objects.filter(store=self.store, face_value=face_value).first()

        if bond:
            self.request.session['bond'] = bond
            return super().form_valid(form)

1 Ответ

1 голос
/ 29 марта 2020

Вы можете перезаписать его вручную в представлении, где у вас будет store_slug:

class ListingView(FormView):

    def get_form(self, form_class=None):
        store_slug = self.kwargs['store_slug']
        form = ListingForm()
        form.fields['face_value'].queryset = Store.objects.filter(anchor=store_slug)
        return form

, а просто заполнитель в форме

class ListingForm(forms.Form):
    face_value = forms.ModelChoiceField(queryset=Store.objects.all())
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...