Проверка встроенного набора форм, обусловленного значением поля из родительской формы

#django #django-views #django-forms

Вопрос:

Я хочу использовать пользовательскую проверку в встроенном наборе форм django ( form_date_event ), чтобы я получал различную проверку в соответствии с одним значением в родительской form_event форме ().

В частности, я бы хотел form_date_event , чтобы встроенный набор форм принимал пустое место, если тип form_event «релиз записи». Как я могу этого достичь? type = cleaned_data.get('type') Нижеприведенное не работает, я полагаю, потому что оно получает clean data набор форм, а не родительскую форму.

models.py :

 
class Venue(models.Model):
    venue_name = models.CharField(max_length=50)


class Event(models.Model):

    EV_TYPE = (
        ('performance', 'performance'),
        ('recording release', 'recording release'),
        ('other', 'other'),
    )
    title = models.CharField(max_length=200)
    type = models.CharField(max_length=20, choices=EV_TYPE, default="performance")


class dateEvent(models.Model):

    venue = models.ForeignKey(Venue, on_delete=models.CASCADE,null=True,blank=True)
    event = models.ForeignKey(Event, on_delete=models.CASCADE)
    start_date_time = models.DateTimeField(auto_now=False, auto_now_add=False)

 

forms.py :

 class EventForm(forms.ModelForm):

    class Meta:
        model = Event
        fields = [
            'type',
            'title',
        ]
 

views.py :

 class BaseDateEventFormSet(BaseInlineFormSet):
    def clean(self):
        cleaned_data = super().clean()
        type = cleaned_data.get('type')

        if type == 'recording release':
            self.add_error('repertoire', _("This field is required"))

        return cleaned_data


def event_edit_view(request, id):
    event = get_object_or_404(Event, id=id)
    active_user = request.user
    form_event = EventForm(request.POST or None, instance=event)
    DateEventFormSet = inlineformset_factory(Event, dateEvent, extra=5, can_delete=True, fields=('event', 'start_date_time', 'venue', 'link', 'link_description'),
    form_date_event = DateEventFormSet(request.POST or None, instance=Event.objects.get(id=id), prefix="dateEvent", queryset=dateEvent.objects.filter(event__id=id))


    context = {
        'event': event,
        'id': event.id,
        'form_event': form_event,
        'form_date_event': form_date_event,

        }

    if request.method == "POST":

        if form_event.is_valid() and request.POST['action'] == 'submit':
            if form_date_event.is_valid():

                flag=False
                evt_type = form_event.cleaned_data.get('type')
                for form in form_date_event:
                    print(form.cleaned_data.get('venue'))
                    if form.cleaned_data.get('venue') is None and evt_type !="recording release":
                        flag = True
                        break
                if flag:
                    messages.error(request,'Venue can be blank only for recording release events')
                    return render(request, "events/event-edit.html", context)
                else:
                    form_event.save()
                    form_date_event.save()
                    return redirect('my-events')
            else:
                raise forms.ValidationError(form_date_event.errors)

        elif form_event.is_valid() and form_date_event.is_valid() and request.POST['action'] == 'update':
            form_event.save()
            form_date_event.save()


        else:
            raise forms.ValidationError([form_event.errors, form_date_event.errors])

    return render(request, "events/event-edit.html", context)
 

Комментарии:

1. что вы имеете в виду, говоря «принять пустое место»? ты имеешь в виду None ?

2. Я имею в виду, что пользователь заполняет/отправляет только start_date и оставляет venue поле нетронутым.

3. это должно быть сделано с учетом того , что вы хотите использовать две формы для выполнения проверки.

4. @Neeraj Это действительно то, что я пытаюсь сделать. Как вы можете видеть из моего вопроса, я говорю, что type = cleaned_data.get('type') в представлении этот трюк не работает. Мне нужно получить type из другой формы. Как?

5. код должен быть написан в функции event_edit_view()

Ответ №1:

Модель события даты измените поле место проведения, venue = models.ForeignKey(Venue, on_delete=models.CASCADE,null=True,blank=True)

в функции event_edit_view() добавьте следующие строки кода

 if form_date_event.is_valid() and form_event.is_valid()
    flag=False
    evt_type = form_event.cleaned_data.get('type')
    for form in form_date_event:
        if form.cleaned_data.get('venue') is None and evt_type !="recording release":
            flag = True
            break
    if flag:
        messages.error(request,'Venue can be blank only for recording release events')
        return render(request,myhtml.html,{'formset':form_date_event,'form':form_event})
    else:
        form_event.save()
        form_date_event.save()
 

Комментарии:

1. Спасибо за это. К сожалению, это работает не так, как ожидалось. У меня есть релиз записи, который я хочу сохранить, со всеми заполненными полями, кроме места проведения, и Django продолжает перенаправлять меня на страницу «редактирование событий» каждый раз, когда я нажимаю кнопку «Сохранить», без ошибок.

2. PS: У меня есть form_event.errors и form_date_event.errors в моем шаблоне.

3. Вы изменили поле «место проведения» в dateEvent?, сохраняются все другие типы событий? Также вы можете сохранить «релиз записи» с помощью «место проведения»?

4. Я забыл отредактировать модель, мой плохой. Итак, я могу сохранить выступление с местом проведения или без него (чего я не хочу: мне нужно обязательное место для выступления), в то время как сейчас я могу сохранить запись без места проведения (тем не менее, я хочу, чтобы это касалось только записи).

5. можете ли вы распечатать form.cleaned_data.get («место проведения») и form_event.cleaned_data.get («тип») в своем представлении, когда вы оставляете его пустым, и скажите мне, что печатается. это значение должно быть проверено в условии «если».