2012-01-25 2 views
1

У меня есть две модели:Ловля проверки ошибок в Джанго образует

class Studio(models.Model): 
    name = models.CharField("Studio", max_length=30, unique=True) 

class Film(models.Model): 
    studio = models.ForeignKey(Studio, verbose_name="Studio") 
    name = models.CharField("Film Name", max_length=30, unique=True) 

У меня есть форма пленки, которая позволяет пользователю либо выбрать уже существующие Studio, или введите новый (с помощью от earlier question:

class FilmForm(forms.ModelForm): 
    required_css_class = 'required' 
    studio = forms.ModelChoiceField(Studio.objects, required=False, widget = SelectWithPlus) 
    new_studio = forms.CharField(max_length=30, required=False, label = "New Studio Name", widget = DeSelectWithX(attrs={'class' : 'hidden_studio_field'})) 

    def __init__(self, *args, **kwargs): 
     super(FilmForm, self).__init__(*args,**kwargs) 
     self.fields['studio'].required = False 

    def clean(self): 
     cleaned_data = self.cleaned_data 
     studio = cleaned_data.get('studio') 
     new_studio = cleaned_data.get('new_studio') 

     if not studio and not new_studio: 
      raise forms.ValidationError("Must specify either Studio or New Studio!") 
     elif not studio: 
      studio, created = Studio.objects.get_or_create(name = new_studio) 
      self.cleaned_data['studio'] = studio 

     return super(FilmForm,self).clean() 

    class Meta: 
     model = Film 

Теперь, мой первый вопрос заключается в том, что, когда обе студии и new_studio не хватает я получаю Джанго ValueError: не могу присвоить None:. «Film.studio» не допускает нулевые значения ошибки Я думал, что захват все ошибки, django никогда не должен заходить так далеко, чтобы реализовать Film.studio пуст.

Вторая проблема - порядок операций. Что делать, если я хочу только сохранить new_studio после того, как я уверен, что остальная часть FilmForm действительна (таким образом предотвращая сохранение кучи названий студий перед тем, как все записи фильма пройдут)? Я в явном виде, или я рискую преждевременным сбережением, потому что new_studio сохраняются в процессе очистки формы?

Edit: Добавлена ​​Traceback и редактируются проверка, если-заявления

+0

Проверьте, что эта строка делает то, что вы имеете в виду: 'if studio is None и new_studio == '':'. Может ли студия быть '' ''или new_studio быть' None'? Правильно ли он показывает ошибку формы, если вы измените ее на 'if not (studio или new_studio):'? – AdamKG

+0

Я положил печать «здесь» прямо перед ValidationError. Он вышел в терминале, поэтому я могу подтвердить, что код достигает этой части. Я попытался изменить критерии, как вы предлагали, и получил ту же ошибку. –

+0

Можете ли вы использовать идентификатор трассировки? – AdamKG

ответ

2

Удалить студию и new_studio от cleaned_data.

if not studio and not new_studio: 
     del cleaned_data['studio'], cleaned_data['new_studio'] 
     raise forms.ValidationError("Must specify either Studio or New Studio!") 
+0

Отлично.Это работает. Любой ввод о том, как предотвратить создание new_studio до остальной формы, полностью подтвержден? Если я вхожу в new_studio, но опускаю имя фильма, форма не проходит, потому что требуется имя, но new_studio создается в любом случае. –

+0

Вы можете изменить 'elif', чтобы быть более конкретным. Убедитесь, что ** studio ** и ** film ** находятся в 'cleaned_data', а затем только создайте новую Studio, если все действительно. – rockingskier

1

FYI по предотвращению presaving из new_studio:

Нового Защиту чистого в виде: четкости чистые (сам): cleaned_data = self.cleaned_data студии = cleaned_data.get ('студия') new_studio = cleaned_data.get ('new_studio')

if not studio and not new_studio: 
     del cleaned_data['studio'], cleaned_data['new_studio'] 
     raise forms.ValidationError("Must specify either Studio or New Studio!") 
    elif not studio: 
     del cleaned_data['studio'] 

    return super(FilmForm,self).clean() 

И в представлении:

def testone(request): 
    if request.method == 'POST': # If the form has been submitted... 
     form = FilmForm(request.POST) # A form bound to the POST data 

     if form.is_valid(): # All validation rules pass 
      if form.cleaned_data['new_studio']: 
       studio, created = Studio.objects.get_or_create(name = form.cleaned_data['new_studio']) 
       new_film = form.save(commit=False) 
       new_film.studio = studio 
      else: 
       new_film = form 

      new_film.save() 
      return HttpResponseRedirect('/') # Redirect after POST 
     else: 
      form = FilmForm() # An unbound form 

     return render_to_response('testone.html', { 
      'form': form 
     }, context_instance=RequestContext(request)) 
Смежные вопросы