2010-10-10 3 views
3

Я новичок в django (до сих пор я использовал Symfony PHP Framework). Моя проблема заключается в следующем: У меня есть модель Событие и модель Дата. Дата имеет внешний ключ для события, так что событие может (или должно) иметь один или несколько дат.Требуется сделать inlineformset в django

Теперь я хочу иметь форму для создания событий, и эта форма должна включать в себя подформу для добавления одной соответствующей даты (дополнительные даты должны быть добавлены позже, если событие имеет более одной даты).

Я использовал inlineformset для реализации подформы Date, но если дата не вводится, ошибка не возникает, и событие сохраняется без даты. Все, что я хочу, - это сделать это inlineformset необходимым или сказать, что в аренде (и только) должен быть один встроенный формат.

Я нашел эти вопросы, но ни один из ответов не помог мне:

Любые намеки на меня?

EDIT: Мне нужно это для интерфейса, а не для бэкэнда. Первая ссылка охватывает его для бэкэнда администратора.

EDIT2: добавлены некоторые исходный код

MandatoryInlineFormSet.py:

from django.forms.models import BaseInlineFormSet 
from django import forms 

class MandatoryInlineFormSet(BaseInlineFormSet): 
    def clean(self): 
     # get forms that actually have valid data 
     count = 0 
     for form in self.forms: 
      try: 
       if form.cleaned_data: 
        count += 1 
      except AttributeError: 
       # annoyingly, if a subform is invalid Django explicity raises 
       # an AttributeError for cleaned_data 
       pass 
     if count < 1: 
      raise forms.ValidationError('You must have at least one order') 

event.py:

from [...] 
def new(request): 
    DateFormset = inlineformset_factory(
      Event, 
      Date, 
      can_delete=False, 
      extra=1, 
      max_num=1, 
      formset=MandatoryInlineFormSet, 
      ) 

    if request.POST: 
     form = EventForm(request.POST) 
     date_formset = DateFormset(request.POST) 
     if form.is_valid(): 
      event = form.save(commit=False) 
      date_formset = DateFormset(request.POST, instance=event) 
      if date_formset.is_valid(): 
       event.save() 
       date_formset.save() 
       return HttpResponseRedirect(reverse('frontpage')) 
    else: 
     form = EventForm() 
     date_formset = DateFormset() 
    return render_to_response('event/new.html', { 
     'form': form, 
     'date_formset': date_formset, 
     }, context_instance=RequestContext(request)) 

событие/new.html:

[...] 
<form action="{% url new-event %}" method="post"> 
    {% csrf_token %} 
    {{ form.as_p }} 

    {{ date_formset.management_form }} 
    {% for date_form in date_formset.forms %} 
     {{ date_form.as_p }} 
    {% endfor %} 


    <input type="submit" value="{% trans "Create event" %}"/> 
</form> 
[...] 

С наилучшими пожеланиями , поручни

+0

Почему мой ответ к первому связанному вопросу помощи? Казалось бы, это ответ на вашу проблему. –

+0

Поскольку это для бэкэнда администратора, мне нужна эта функциональность в интерфейсе (я забыл упомянуть об этом). Я попытался использовать ваш код для frontend, но это не сработало. – sewid

+0

Я не понимаю, почему это не сработает o с администратором. Просто создайте inlineformset в коде вида. –

ответ

1

Я сам случайно обрушился на это сам. У меня был встроенный набор форм, на котором было modelchoicefield. У этого modelchoice не было empty_label. Так что технически это было не совсем пусто. Когда другие поля были оставлены в встроенной форме, они отображали ошибки проверки (вы можете легко проверить это в представлении и не сохранять основную форму, если все встроенные формы не действительны).

Итак, кажется, что у вас остались два варианта: 1) заполнить форму даты недействительным текстом (то есть не дату, «вспомогательный» текст какого-либо типа), который, когда он оставлен и отправлен, не может проверить, или 2) переделать свой селектор даты в выпадающие виджеты, которые не имеют пустого состояния, - заставляя пользователя что-то выбирать (но вы можете предпочесть правильный виджет даты javascript, который сделает несколько выпадающих списков обременительными.

+0

спасибо! У меня была такая же ошибка;) – dnaranjo

Смежные вопросы