2012-01-07 1 views
38

모델의 save 메소드에서 유효성 검증 오류를 올바르게 발생시키고 사용자에게 명확한 메시지를 다시 보내는 방법을 모르겠습니다.Django의 모델 저장 메소드에서 유효성 검사 오류 발생

기본적으로 내가 알고 싶은 방법의 각 부분 끝나야한다 "만일"나는 오류 를 제기 할 하나 실제로 저장하는 하나

def save(self, *args, **kwargs): 
    if not good_enough_to_be_saved: 
     raise ValidationError 
    else: 
     super(Model, self).save(*args, **kwargs) 

가 그럼 난 알고 싶어 예를 들어 값이 고유하지 않은 경우 Django가 자동으로 반환하는 것과 같은 잘못된 내용을 사용자에게 정확하게 알려주는 유효성 검사 오류를 보내려면 어떻게해야할까요? (ModelForm)을 사용하고 있으며 모델의 모든 것을 조정하고 있습니다.

답변

32

대부분의 장고보기 Django 관리자는 save 메소드에서 유효성 검사 오류를 처리 할 수 ​​없으므로 사용자는 500 개의 오류를 받게됩니다.

모델 양식 또는 모델에서 유효성 검사를 수행하고 ValidationError을 제기해야합니다. 그런 다음 모델 양식 데이터가 '저장하기에 충분 함'인 경우에만 save()으로 전화하십시오.

+0

당신이 바로 내가에 내 검증을 이동있어 양식, 그것은 더 쉬운 방법입니다. 방금 모델에 모든 것을 넣을 생각이 맘에 들어요. – Bastian

+8

@bastian, 나는 또한 모든 것을 모델에 넣는 것을 좋아했습니다. 새 양식을 작성할 때 비즈니스 규칙을 잊어 버릴 수는 있지만 비즈니스 규칙이 모델에 포함되어있는 것은 아닙니다. 이러한 이유로 저는 게시물에서 설명하는대로 양식에서 모델로 유효성 검사를 이동했습니다. 나는 그것이 더 우아한 방법으로 이것을하는 새로운 방법에 대해 배우기 위해 열려 있습니다. 어쨌든 양식에 유효성 검사 코드를 쓰는 것을 피합니다. – danihp

+6

유효성 검사기를 사용하거나'clean()'메소드를 작성하여 모델에 유효성 검사를하는 것이 좋습니다. 내가 말한 것은'save()'메소드가 정확한 위치가 아니라는 것입니다. [validating objects] (https://docs.djangoproject.com/en/dev/ref/models/instances/#validating-objects)에서 문서를보십시오. – Alasdair

22

바스티안, 나는 당신에게 내 코드 템플릿을 설명, 나는 당신에게 도움이되기를 바랍니다 : django 1.2 it is able to write validation code on model 이후

합니다. modelforms로 작업 할 때 instance.full_clean()이 폼 유효성 검사에서 호출됩니다. 각 모델에서

나는 (이 방법은 자동으로 modelform 검증에() full_clean에서 호출) 사용자 정의 기능 clean() 방법을 덮어 :

from django.db import models 

class Issue(models.Model): 
    .... 
    def clean(self): 
     rules.Issue_clean(self) #<-- custom function invocation 

from issues import rules 
rules.connect() 

그런 다음 rules.py 파일에 내가 bussiness의 규칙을 작성합니다.

def connect():  
    from django.db.models.signals import post_save, pre_save, pre_delete 
    #issues 
    pre_save.connect(Issue_pre_save, sender = Incidencia) 
    post_save.connect(Issue_post_save, sender = Incidencia) 
    pre_delete.connect(Issue_pre_delete, sender= Incidencia) 

def Incidencia_clean(instance): #<-- custom function 
    import datetime as dt  
    errors = {} 

    #dia i hora sempre informats  
    if not instance.dia_incidencia: #<-- business rules 
     errors.setdefault('dia_incidencia',[]).append(u'Data missing: ...') 

    #dia i hora sempre informats  
    if not instance.franja_incidencia: 
     errors.setdefault('franja_incidencia',[]).append(u'Falten Dades: ...') 

    #Només es poden posar incidències més ennlà de 7 dies 
    if instance.dia_incidencia < (dt.date.today() + dt.timedelta(days = -7)): 
     errors.setdefault('dia_incidencia 1',[]).append(u'''blah blah error desc)''') 

    #No incidències al futur. 
    if instance.getDate() > datetime.now(): 
     errors.setdefault('dia_incidencia 2',[]).append(u'''Encara no pots ....''') 
    ... 

    if len(errors) > 0: 
     raise ValidationError(errors) #<-- raising errors 

def Issue_pre_save(sender, instance, **kwargs): 
    instance.clean()  #<-- custom function invocation 

그런 issues.models 수입 문제에서

, modelform 모델의 청소 방법 및 올바른 상태에 대한 내 custon 기능 검사를 호출 또한 내가 잘못 상태 모델을 저장 방지하기 위해 내 사용자 지정 기능에 pre_save() 연결 모델 양식에서 처리하는 오류를 발생시킵니다.

양식의 오류를 표시하려면 양식 서식 파일에 포함되어야합니다

{% if form.non_field_errors %} 
     {% for error in form.non_field_errors %} 
     {{error}} 
     {% endfor %} 
{% endif %} 

이유는 non_field_errors 오류 사전 항목에 바인더 제본이 모델 검증하는 오류 제단이다.

저장하거나 당신이 오류가 발생 될 수 있음을 유의 형태 중 모델 삭제 :

try: 
     #provoco els errors per mostrar-los igualment al formulari. 
     issue.clean() 
    except ValidationError, e: 
     form._errors = {} 
     for _, v in e.message_dict.items(): 
      form._errors.setdefault(NON_FIELD_ERRORS, []).extend( v ) 
: 또한

try: 
    issue.delete() 
except ValidationError, e: 
    import itertools 
    errors = list(itertools.chain(*e.message_dict.values())) 

, 당신은 어떤 modelforms에 양식 사전에 오류를 추가 할 수

이 코드는 save() 메서드에서 실행되지 않습니다. 모델의 save() 메서드를 호출 할 때 full_clean()이 자동으로 호출되지 않으며 ModelForm 유효성 검사의 결과로도 사용되지 않습니다.그런 다음 없는 modelforms에 양식 사전에 오류를 추가 할 수 있습니다뿐만 아니라 ValidationError를 가져해야

try: 
     #provoco els errors per mostrar-los igualment al formulari. 
     issue.clean() 
    except ValidationError, e: 
     form._errors = {} 
     for _, v in e.message_dict.items(): 
      form._errors.setdefault(NON_FIELD_ERRORS, []).extend( v ) 
+1

긴 설명을위한 몰트 그림. 나는 자동, Djangoish 무언가를 찾고 있었다. 귀하의 예를 들어 다른 상황에 관심이있을 수도 있지만 지금 내가 쓰고있는 하나의 라인 유효성 검사 그래서 내가 여기에 모든 것을 구현하지 않습니다. – Bastian

+3

당신은 오신 것을 환영합니다. 카탈루냐를 언젠가 방문하는 것을 잊지 마세요 :) – danihp

+7

바르셀로나에 살고 있습니다 :) – Bastian

1

from django.core.exceptions import ValidationError 
-1
def clean(self): 
    raise ValidationError("Validation Error") 

def save(self, *args, **kwargs): 
    if some condition: 
     #do something here 
    else: 
     self.full_clean() 
    super(ClassName, self).save(*args, **kwargs) 
+1

게시 코드로는 충분하지 않습니다. – Ivan

+0

저장 함수에서 full_clean() 메서드를 호출 할 수 있습니다. 장고 == 1.11에서 정상적으로 작동합니다. 이전 버전에 대해서는 잘 모르겠습니다. –

+0

이 정보를 개선하기 위해 답을 추가하십시오. – Ivan