Django: проверка ограниченных форм внешних ключей в представлениях класса Mixins - PullRequest
0 голосов
/ 26 апреля 2020

Контекст: как я обработал ограничения внешних ключей для GET

У меня возникли проблемы при проверке этого form:

class RecordConsultationForm(forms.ModelForm):
    class Meta:
        model = Consultation
        fields = ["fk_type", "fk_client", "duration", "date"]

    def __init__(self, *args, **kwargs):
        self.user = kwargs.pop('user', None)
        super(RecordConsultationForm, self).__init__(*args, **kwargs)
        self.fields['fk_client'].queryset = Client.objects.filter(fk_owner=self.user) # <=====HERE

queryset ограничивает доступные клиенты до пользователи . Довольно эффективно, мне просто нужно было добавить следующее к get_context_data():

@method_decorator(login_required, name='dispatch')
class BrowseConsultations(BrowseAndCreate):
    template_name = "console/browse_consultations.html"
    model = Consultation
    form_class = RecordConsultationForm
    success_url = 'browse_consultations'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['form'] = self.form_class(user = self.request.user)  #<=====HERE
        return context

    def post(self, request): 
        form = self.form_class(user = self.request.user) #<=====HERE
        return super().post(request)

Проверка формы на BrowseConsultations

Несмотря на то, что я добавил в get_context_data() и post(), форму данные по POST не кажутся действительными, как если бы пользователь был None (так кажется):

Invalid fk_client: Select a valid choice. 2 is not one of the available choices.

Может быть get_context_data() не было подходящим местом для установки пользователя? Есть ли способ, которым я мог бы настроить форму в post()? Это правильный способ сделать это?

Дополнительные сведения

BrowseAndCreate BrowseConsultations наследует от класса Mixing, который я создал для обработки общих задач и сообщений заказа. Вот его часть:

@method_decorator(login_required, name='dispatch')
class BrowseAndCreate(CreateView, TemplateView):
    """display a bunch of items from a model and the form to create new instances"""

    def post(self, request):
        super().post(request)
        return redirect(self.success_url)

    def form_valid(self, form):
        super().form_valid(form)
        messages.add_message(self.request, messages.SUCCESS,
                             "Recorded in {}".format(self.object.status))

    def form_invalid(self, form):
        for e in form.errors.items():
            messages.add_message(self.request, messages.WARNING,
                                 "Invalid {}: {}".format(e[0], e[1][0]))

Среда

  • django 3.0.4
  • python 3.7

1 Ответ

0 голосов
/ 27 апреля 2020

Прежде всего, CreateView (от которого наследуется ваше BrowseAndCreate) обрабатывает проверку формы в методе post, где он вызывает form_valid в случае успеха и form_invalid в случае неудачи. Оба эти метода должны возвращать HTTP-ответ.

Кроме того, get_context_data из FormMixin, который вы переопределяете, уже заботится о получении данных формы.

Если вам нужен user в вашей форме, вы можете иметь это в вашей форме:

class RecordConsultationForm(forms.Form):

    def __init__(self, user, *args, **kwargs):
        self.user = user
        super().__init__(*args, **kwargs)

И это по вашему мнению:

class BrowseConsultations(BrowseAndCreate):

    def get_form_kwargs(self):
        kwargs = super().get_form_kwargs()
        kwargs['user'] = self.request.user
        return kwargs
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...