Django의 모델 저장 방법에서 유효성 검사 오류 발생
모델의 저장 방법에서 유효성 검사 오류를 올바르게 제기하고 사용자에게 명확한 메시지를 다시 보내는 방법을 잘 모르겠습니다.
기본적으로 "if"의 각 부분이 어떻게 끝나야하는지, 오류를 발생시키고 싶은 부분과 실제로 저장하는 부분을 알고 싶습니다.
def save(self, *args, **kwargs):
if not good_enough_to_be_saved:
raise ValidationError
else:
super(Model, self).save(*args, **kwargs)
그런 다음 예를 들어 값이 고유하지 않은 경우 Django가 자동으로 반환하는 것과 같이 사용자에게 정확히 무엇이 잘못되었는지를 알려주는 유효성 검사 오류를 보내려면 어떻게해야하는지 알고 싶습니다. (ModelForm)을 사용하고 모델의 모든 것을 조정합니다.
대부분의 Django 뷰 (예 : Django 관리자)는 save 메소드에서 유효성 검사 오류를 처리 할 수 없으므로 사용자는 500 오류를 받게됩니다.
모델 양식 또는 모델에서 유효성 검사를 수행하고 ValidationError
거기에서 제기 해야합니다. 그런 다음 save()
모델 양식 데이터가 '저장하기에 충분'한 경우에만 호출 하십시오.
Bastian, 내 코드 템플릿에 대해 설명합니다. 도움이 되었기를 바랍니다.
django 1.2 부터 model에서 유효성 검사 코드를 작성할 수 있습니다 . modelforms로 작업 할 때 form 유효성 검사시 instance.full_clean ()이 호출됩니다.
각 모델에서 clean()
메서드를 사용자 지정 함수로 덮어 씁니다 (이 메서드는 modelform 유효성 검사시 full_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
파일에 비즈니스 규칙을 작성합니다. 또한 pre_save()
잘못된 상태로 모델을 저장하지 않도록 사용자 지정 함수에 연결 합니다.
issues.models에서 import Issue
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
그런 다음 modelform은 모델의 clean 메서드를 호출하고 내 custon 함수가 올바른 상태를 확인하거나 모델 형식에서 처리하는 오류를 발생시킵니다.
양식에 오류를 표시하려면 다음을 양식 서식 파일에 포함해야합니다.
{% if form.non_field_errors %}
{% for error in form.non_field_errors %}
{{error}}
{% endfor %}
{% endif %}
그 이유는 모델 유효성 검사 오류가 non_field_errors 오류 사전 항목에 바인딩 되었기 때문입니다.
양식에서 모델을 저장하거나 삭제할 때 오류가 발생할 수 있음을 기억해야합니다.
try:
issue.delete()
except ValidationError, e:
import itertools
errors = list( itertools.chain( *e.message_dict.values() ) )
또한 모델 양식이없는 양식 사전에 오류를 추가 할 수 있습니다.
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 )
이 코드는 save () 메서드에서 실행되지 않는다는 점을 기억하십시오. full_clean ()은 모델의 save () 메서드를 호출 할 때 자동으로 호출되지 않으며 ModelForm 유효성 검사의 결과로도 호출되지 않습니다. 그런 다음 modelforms 가 없는 양식 사전에 오류를 추가 할 수 있습니다 .
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 )
ValidationError도 가져와야합니다.
from django.core.exceptions import ValidationError
I think this is more clear way to do that for Django 1.2+
In forms it will be raised as non_field_error, in other cases, like DRF you have to check this case manual, because it will be 500 error.
class BaseModelExt(models.Model):
is_cleaned = False
def clean(self):
# check validation rules here
self.is_cleaned = True
def save(self, *args, **kwargs):
if not self.is_cleaned:
self.clean()
super().save(*args, **kwargs)
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)
Edit: This answer assumes that you have a scenario that does not allow you to edit the currently implemented User
class, because you are not starting a project from scratch, the current implementation does not already use a custom User class, and you instead have to figure out how to accomplish this task by modifying Django's built in User model behavior.
You can just stick a clean
method to your model most of the time, but you don't have that option necessarily with the built in auth.User
model. This solution will allow you to create a clean
method for the auth.User
model in such a way that ValidationError
s will propagate to forms where the clean method is called (including admin forms).
The below example raises an error if someone attempts to create or edit an auth.User
instance to have the same email address as an existing auth.User
instance. Disclaimer, if you are exposing a registration form to new users, you do not want your validation error to call out usernames as mine does below.
from django.contrib.auth.models import User
from django.forms import ValidationError as FormValidationError
def clean_user_email(self):
instance = self
super(User, self).clean()
if instance.email:
if User.objects.filter(id=instance.id, email=instance.email).exists():
pass # email was not modified
elif User.objects.filter(email=instance.email).exists():
other_users = [*User.objects.filter(email=instance.email).values_list('username', flat=True)]
raise FormValidationError(f'At least one other user already has this email address: '
f'{", ".join(other_users)}'
, code='invalid')
# assign the above function to the User.clean method
User.add_to_class("clean", clean_user_email)
I have this at the bottom of my_app.models
but I am sure it would work as long as you stick it somewhere that is loaded before the form in question.
ReferenceURL : https://stackoverflow.com/questions/8771029/raise-a-validation-error-in-a-models-save-method-in-django
'program story' 카테고리의 다른 글
Maven에서 메시지를 어떻게 표시 할 수 있습니까? (0) | 2021.01.08 |
---|---|
정규식 : 0 개 이상의 선택적 문자 / (0) | 2021.01.08 |
randomForest (R 패키지)에 대한 데이터를 정규화 (또는 확장)해야합니까? (0) | 2021.01.08 |
Joda-Time Interval과 비슷한 java.time 클래스가 있습니까? (0) | 2021.01.08 |
매니페스트 파일이 다른 Android Studio 두 가지 버전 (0) | 2021.01.08 |