Dans mon application alimentée par Django, il n'y a qu'un seul cas évident où "IntegrityError" peut survenir.
Alors, comment puis-je détecter cette erreur et afficher un message à l'aide de modèles?
Utilisez juste essayer et attraper.
from Django.db import IntegrityError
from Django.shortcuts import render_to_response
try:
# code that produces error
except IntegrityError as e:
return render_to_response("template.html", {"message": e.message})
Si vous le souhaitez, vous pouvez utiliser le message dans votre modèle.
MODIFIER
Merci pour Jill-Jênn Vie , vous devez utiliser e.__cause__
, comme décrit ici .
Si vous utilisez des vues basées sur les classes avec le mixin CreateView, vous voudrez "essayer" l'appel à la valeur_formulaire de la superclasse, par exemple:
from Django.db import IntegrityError
...
class KumquatCreateView(CreateView):
model = Kumquat
form_class = forms.KumquatForm
...
def form_valid(self, form):
...
try:
return super(KumquatCreateView, self).form_valid(form)
except IntegrityError:
return HttpResponse("ERROR: Kumquat already exists!")
Vous pouvez utiliser un modèle, render_to_response
etc. pour rendre la sortie plus agréable, bien sûr.
Solution la plus simple: écrivez un middleware implémentant process_exception
qui ne capture que IntegrityError et renvoie une réponse HttpResponse avec votre modèle de rendu, et assurez-vous qu'il est après le middleware de traitement des erreurs par défaut, de sorte qu'il est appelé avant (cf https: //docs.djangoproject. com/fr/dev/topics/http/middleware/# process-exception pour les autres).
Maintenant, si j'étais vous, je ne supposerais pas une chose comme "il n'y a qu'un seul cas évident où" IntegrityError "puisse survenir", c'est pourquoi je vous recommande fortement de consigner l'exception (et d'envoyer des alertes par e-mail) dans votre middleware.
Je le validerais avec ModelForm. Par exemple:
Vous avez un modèle:
class Manufacturer(models.Model):
name = models.CharField(default='', max_length=40, unique=True)
Et ModelForm:
class ManufacturerForm(forms.ModelForm):
def clean(self):
cleaned_data = super(ManufacturerForm, self).clean()
name = cleaned_data.get('name')
if Manufacturer.objects.filter(name=name).exists():
raise forms.ValidationError('Category already exists')
class Meta:
model = Manufacturer
Dans ce cas, lorsque vous soumettez un nom unique. Vous obtiendrez une erreur de validation avant IntegrityError. Le message 'La catégorie existe déjà' sera affiché dans votre formulaire dans le modèle
Importez simplement IntegrityError
de Django.db import IntegrityError
C'est tout.
Je l'ai fait comme ça
from Django.db import IntegrityError
from Django.shortcuts import render
from .models import Person
from .forms import PersonForm
class PersonView(View):
def get(self, request):
pd = PersonForm()
return render(request, "app1/my_form.html", context={ 'form': pd })
def post(self, request):
pd = PersonForm(request.POST)
if pd.is_valid():
name = pd.cleaned_data['name']
age = pd.cleaned_data['age']
height = pd.cleaned_data['height']
p = Person()
p.name = name
p.age = age
p.height = height
try:
p.save()
except IntegrityError as e:
e = 'this data already exists in the database'
return render(request, "app1/my_form.html", context={ 'form': pd, 'e': e})
context = {
'person': {
'name': name,
'age': age,
'height': height,
},
'form': pd
}
else:
print("Form is invalid")
context = { 'form': pd }
return render(request, "app1/my_form.html", context=context)
dans le modèle, je peux accéder à l'erreur en tant que {{e}}