У меня есть модель Джанго, которая выглядит следующим образом.
class Solution(models.Model):
'''
Represents a solution to a specific problem.
'''
name = models.CharField(max_length=50)
problem = models.ForeignKey(Problem)
description = models.TextField(blank=True)
date = models.DateTimeField(auto_now_add=True)
class Meta:
unique_together = ("name", "problem")
Я использую форму для добавления моделей, которая выглядит следующим образом:
class SolutionForm(forms.ModelForm):
class Meta:
model = Solution
exclude = ['problem']
Моя проблема в том, что SolutionForm
не проверяет ограничение Solution
unique_together
и, таким образом, возвращает IntegrityError
при попытке сохранить форму. Я знаю, что мог бы использовать validate_unique
для ручной проверки этого, но мне было интересно, есть ли способ поймать это в проверке формы и автоматически вернуть ошибку формы.
Спасибо.
Мое решение базируется от Django 2.1
, Оставляют SolutionForm в покое, имеют сохранение (), метод в Решении
class Solution(models.Model):
...
def save(self, *args, **kwargs):
self.clean()
return super(Solution, self).save(*args, **kwargs)
def clean():
# have your custom model field checks here
# They can raise Validation Error
# Now this is the key to enforcing unique constraint
self.validate_unique()
, Звоня full_clean () в сохранении () не работает, поскольку ValidationError будет не обработан
Я должен был исключить company
поле в моем случае и добавить его в представлении form_valid
функция. Я закончил тем, что делал следующее (берущий вдохновение из различных ответов). В моем CreateView
def form_valid(self, form):
cleaned_data = form.cleaned_data
user_company = self.request.user.profile.company
if UnitCategory.objects.filter(code=cleaned_data['code'],
company=user_company).exists():
form.add_error('code', _(
'A UnitCategory with this Code already exists for this company.'))
return super(UnitCategoryCreateView, self).form_invalid(form)
if UnitCategory.objects.filter(color=cleaned_data['color'],
company=user_company).exists():
form.add_error('color', _(
'A UnitCategory with this Color already exists for this company.'))
return super(UnitCategoryCreateView, self).form_invalid(form)
form.instance.company = user_company
return super(UnitCategoryCreateView, self).form_valid(form)
В моем UpdateView
я должен был исключить текущий экземпляр объекта в проверке, если запрос существует с помощью exclude(pk=self.kwargs['pk'])
def form_valid(self, form):
cleaned_data = form.cleaned_data
user_company = self.request.user.profile.company
if UnitCategory.objects.filter(code=cleaned_data['code'],
company=user_company).exclude(pk=self.kwargs['pk']).exists():
form.add_error(
'code', _('A UnitCategory with this Code already exists for this company.'))
return super(UnitCategoryUpdateView, self).form_invalid(form)
if UnitCategory.objects.filter(color=cleaned_data['color'],
company=user_company).exclude(pk=self.kwargs['pk']).exists():
form.add_error('color', _(
'A UnitCategory with this Color already exists for this company.'))
return super(UnitCategoryUpdateView, self).form_invalid(form)
# Return form_valid if no errors raised
# Add logged-in user's company as form's company field
form.instance.company = user_company
return super(UnitCategoryUpdateView, self).form_valid(form)
Не самое чистое решение, я надеялся на, но думал, что это могло бы принести пользу кому-то.