2009-10-26 1 views
53

모델 필드의 유효성 검사는 어디에서 django로 가야합니까?Django 모델 필드 유효성 검사

모델의 오버로드 된 .save() 메소드 또는 모델의 .to_python() 메소드에서 이름을 지정할 수 있습니다. 필드 하위 클래스 (분명히 사용자 정의 필드를 작성해야합니다) .

가능한 사용 사례 :

  • 이 보장하는 절대적이 켜지지입니다

    는, 빈 문자열은 데이터베이스에 기록되지 않습니다 (빈 = 거짓 키워드 인수가 여기에 작동하지 않습니다, 그것은 양식입니다 그것은 "선택"키워드 인수는 데시벨 수준에 존경과 열거 데이터 유형을) 모방뿐만 아니라 관리 인터페이스에서 (종류 도착 것을 보장하기 위해이 켜지지 때 유효성 검사 만)
  • 는 는

도있다

  • 클래스 수준 특성 empty_strings_allowed. models.Field 기본 클래스 정의 및 파생 클래스는 행복하게 재정의하지만 데이터베이스 수준에 아무런 영향을주지 않는 것으로 보입니다. 따라서 빈 문자열 필드가있는 모델을 만들고 데이터베이스에 저장할 수 있습니다. 어느 것을 피하고 싶습니다 (예, 필요합니다).

    class CustomField(models.CharField): 
        __metaclass__ = models.SubfieldBase 
        def to_python(self, value): 
         if not value: 
          raise IntegrityError(_('Empty string not allowed')) 
         return models.CharField.to_python(self, value) 
    

    모델 수준 :

    가능한 구현 필드 레벨에

    이다 아마도

    class MyModel(models.Model) 
        FIELD1_CHOICES = ['foo', 'bar', 'baz'] 
        field1 = models.CharField(max_length=255, 
           choices=[(item,item) for item in FIELD1_CHOICES]) 
    
        def save(self, force_insert=False, force_update=False): 
         if self.field1 not in MyModel.FIELD1_CHOICES: 
          raise IntegrityError(_('Invalid value of field1')) 
         # this can, of course, be made more generic 
         models.Model.save(self, force_insert, force_update) 
    

    , 내가 뭔가를 놓친 거지이 쉽게 수행 할 수 있습니다 (그리고 청소기)? 난 당신이 "명확하게"이해한다면

  • 답변

    55

    장고에는 버전 1.2 이후로 model validation 시스템이 있습니다.

    의견에서 sebpiq는 "이제는 모델 유효성 확인을 할 수있는 곳이 있습니다 ... ModelForm을 사용할 때만 실행된다는 점만 제외하면 문제가 남아 있으므로 확인이 존중되도록해야합니다. db 레벨, 당신은 무엇을해야합니까? full_clean을 호출 할 곳은 어디입니까? "

    파이썬 수준 유효성 검사를 통해 유효성 검사가 db 수준에서 보장되는지 여부를 확인할 수 없습니다. 가장 가까운 것은 대체 된 save 메서드에서 full_clean을 호출하는 것입니다. 이것은 save 메소드를 호출하는 모든 사람들이 이제는 ValidationError을 잡아서 처리하는 것이 더 좋았 기 때문에 기본적으로 수행되지 않습니다.

    하지만 이렇게해도 누군가가 queryset.update()을 사용하여 모델 인스턴스를 대량으로 업데이트 할 수 있습니다.이 유효성 검사는 무시됩니다.Django가 모든 업데이트 된 객체에 대해 Python 수준의 유효성 검사를 여전히 수행 할 수있는 비교적 효율적인 queryset.update()을 구현할 수있는 방법은 없습니다.

    db 수준의 무결성을 보장하는 유일한 방법은 db 수준 제약 조건을 사용하는 것입니다. ORM을 통해 수행하는 모든 유효성 검사는 유효성 검사가 적용되는시기를 인식하고 유효성 검사 오류를 처리하는 앱 코드 작성자를 요구합니다.

    이 이유는 모델 유효성 검사가 기본적으로 ModelForm에만 적용되는 이유입니다. ModelForm에서 이미 ValidationError을 처리 할 분명한 방법이 있기 때문입니다.

    +0

    위대한, 위대한, 이건 그냥 대단해! 내가 소스를 통해 건너 뛴다. (그런데, 트렁크로 할 수있는 것처럼 문서에 접근 할 수있는 방법이 있는가?) 내가 필요로하는 것처럼 보인다. 내 말은, 나는 모두 내 자신을 굴리기위한 것이지만, 장고는 일을하는 통일 된 방법을 제공함에있어서 우수하다고 (잘, IMO, 어쨌든). – shylent

    +2

    해당 분기를 확인하고 docutils 및 Sphinx가 설치되어 있는지 확인한 다음 docs/디렉토리로 이동하여 "make html"을 실행하십시오. Django 웹 사이트에있는 것처럼 HTML 형식으로 문서를 작성해야하며 로컬로 액세스 할 수 있습니다. –

    +0

    필자는 문서가 모델 유효성 검사에 대해 아무 것도 말하지 않았기 때문에 소스 (특히'models/fields/__ init __. py', models/base.py 및 core/validators.py)를 읽지 않았습니다. 그러나 양식 유효성 검사와 거의 동일하게 작동한다는 점에 유의해야합니다 (적어도 일반 논리는 거의 동일합니다). 어쨌든, 이것은 제가 찾고 있었던 것입니다. 트렁크에서이 지점으로 전환하면 내 앱이 끔찍하게 부서지지 않기를 바랍니다. – shylent

    1

    - 당신이 기능 get_db_prep_save 대신 to_python 이에 대한

    +0

    . 그러나 특히 필드를 초기화 한 후에 (__metaclass__ = models.SubfieldBase를 지정하면) 시작되므로 검증이 일찍 발생하므로 모델을 초기화 할 수 없다는 것을 의미하므로 .to_python()을 언급했습니다. 필드의 값이 잘못되었습니다. 아마, 당신의 방법은 올바른 방법입니다. 적어도 그것은 나에게 어떤 의미가 있습니다. – shylent

    +0

    그래서 둘 다 무시하십시오. – Oduvan

    3

    루트 문제를 재정의해야합니다, 검증이 모델에서 발생해야한다는 것입니다. 이것은 장고 (dev 메일 링리스트에 대한 검색 양식 모델 인식 검증)에서 오랫동안 논의되어 왔습니다. 그것은 중복 또는 db를 치기 전에 유효성 검사를 벗어나는 것에 이르게합니다.

    트렁크에 닿지는 않지만 Malcolm의 "poor man's model validation solution"은 반복적 인 반복을 피하는 가장 안전한 솔루션 일 것입니다.

    +1

    링크가 깨졌습니다 ... –

    +0

    Google 캐시에서 내용을 읽었습니다. 네 말이 맞아. 양식을 사용하지 않을 경우 (데이터를 입력하는 데 양식이 필요하지는 않습니까?),별로 도움이되지는 않지만 반복되는 것을 피하는 방법은 분명합니다. – shylent

    6

    난 당신이 원하는 생각이 -> (http://djangosnippets.org/snippets/2319/에서 복사)

    from django.db.models.signals import pre_save 
    
    def validate_model(sender, **kwargs): 
        if 'raw' in kwargs and not kwargs['raw']: 
         kwargs['instance'].full_clean() 
    
    pre_save.connect(validate_model, dispatch_uid='validate_models') 
    

    실제로 좋은 생각

    +0

    아니요. 모델 유효성 검사가 순간적으로 장고에 있기 때문에 원본 질문의 요점은 다소 의문입니다 – shylent

    +2

    유효성 검사기를 저장하면 실행할 필요가 없으므로 그렇게 생각하지 않습니다. 그렇게하지 않으면 물건을 추가 할 수 있습니다. 유효성 검사. http://docs.djangoproject.com/en/dev/releases/1.2/#model-validation "모델 인스턴스의 save() 메소드를 호출하기 만하면 인스턴스 데이터의 유효성 검사가 수행되지 않습니다." OP가 원하는 것을 오해했을 지 모르지만 * * 확실히 save()의 유효성 검사 방법을 원합니다 :) – Darius