#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 («тип») в своем представлении, когда вы оставляете его пустым, и скажите мне, что печатается. это значение должно быть проверено в условии «если».