Django

2012-01-07 16 views
38

modelinde bir modelin kaydetme yöntemindeki bir doğrulama hatasını yükseltin Bir modelin kaydetme yönteminde bir doğrulama hatasını doğru bir şekilde nasıl yükseltebileceğimi ve kullanıcıya net bir mesaj gönderdiğinden emin değilim.Django

Temelde bilmek istiyorum nasıl her parçası bitmeli "eğer" Ben hata yükseltmek istiyorum bir ve aslında kaydeder tek:

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

Sonra bilmek istiyorum Kullanıcıya tam olarak ne dediği gibi bir doğrulama hatası göndermek için yapmanız gereken tek şey bir Django'nun örneğin bir değer benzersiz değilse otomatik olarak geri döndüğü gibidir. Bir (ModelForm) kullanıyorum ve modelden her şeyi ayarladım.

cevap

32

Çoğu Django görünümü örn. Django yöneticisi, kaydetme yönteminde bir doğrulama hatasıyla başa çıkamaz, böylece kullanıcılarınız 500 hata alır.

Model formunda veya modelde doğrulama yapmalı ve orada ValidationError'yi yükseltmelisiniz. Daha sonra model form verileri 'kaydetmek için yeterince iyi' ise save()'u arayın.

+0

Haklısınız ben içine benim doğrulama hareket edecek konum form, daha kolay. Modelde herşeye sahip olma fikrini çok beğendim. – Bastian

+8

@bastian, Ben de her şey modelinde sahip olmak isterdim. Yeni bir form yazdığınızda bir işletme kuralını unutmak kolaydır, ancak iş kuralları modelde değilse. Bu nedenle yazımda açıkladığım gibi doğrulamaları formlardan modele taşıdım. Varsa daha zarif bir şekilde bunu yapmak için yeni yöntemler hakkında bilgi edinmek için açıkım. Her halükarda, formlarda doğrulama kodu yazmamaktayım. – danihp

+6

Doğrulama kullanarak veya bir "clean()" yöntemini yazarak, modelinize doğrulama koymak iyi olur. Tüm söylediğim 'save()' yöntemi doğru yer değil. [Nesneleri onaylama] konusundaki dokümanlara bir göz atın (https://docs.djangoproject.com/en/dev/ref/models/instances/#validating-objects). – Alasdair

22

Bastian, sana benim kod çiftleşmiş açıklamak, bunu sana yardımcı olur umarım: django 1.2 it is able to write validation code on model yana

. Model formları ile çalıştığımızda, form validation üzerinde instance.full_clean() çağrılır. Her bir modelde

I (bu yöntem otomatik olarak modelform doğrulama ile ilgili() full_clean denir) özel bir fonksiyon ile clean() yöntemi üzerine:

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() 

sonra rules.py dosyasında orada var iş kuralları bilgileri.

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 

Sonra issues.models ithalat sayısından

, modelform modelin temiz yöntem ve bir durumum benim custon işlev kontrolünü çağırır: Ayrıca ben yanlış durumda bir model kaydetmek önlemek için benim özel işlevine pre_save() bağlamak veya model formuna göre işlenen bir hatayı kaldırın.

form üzerindeki hataları göstermek için, form şablonunda bu içermelidir:

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

nedeni non_field_errors hata sözlük girişinin binded o model doğrulama erros ara olduğunu.

kaydetmek veya bir hata ortaya edilebilir hatırlamalıyız bir form dışında bir model silin:

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 ) 
: Ayrıca

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

, hiçbir modelforms bir form sözlüğe hataları ekleyebilir

Bu kodun save() yönteminde yürütülmediğini unutmayın: Modelinizin save() yöntemini çağırdığınızda veya ModelForm doğrulamasının sonucu olarak full_clean() işlevi otomatik olarak çağrılmayacağını unutmayın.Ardından, hiçbir modelforms bir form sözlüğe hataları ekleyebilirsiniz: yanı ValidationError içe emin olun

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

Uzun açıklamalarınız için molte grileri. Otomatik bir şey arıyordum Djangoish. Örneğiniz başka durumlar için beni ilgilendirebilir ama şimdi yazdığım sadece 1 satırlık bir doğrulamadır, bu yüzden burada her şeyi uygulamayacağım. – Bastian

+3

Bir şey değil. Bir gün Katalonya'yı ziyaret etmeyi unutmayın :) – danihp

+7

Barselona'da yaşıyorum :) – 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

Posta kodu yeterli değil, bazı açıklamalar vermelisiniz. – Ivan

+0

kayıt işlevinde full_clean() yöntemini çağırabilirsiniz, bu Django == 1.11'de düzgün çalışıyor, eski sürümden emin değilim. –

+0

Bu bilgiyi geliştirmek için cevabınıza ekleyin. – Ivan