Проверка модели Django ManyToMany
У меня есть модель с ManyToManyField, подобная этой (модель Word также имеет язык):
class Sentence(models.Model):
words = models.ManyToManyField(Word)
language = models.ForeignKey(Language)
def clean(self):
for word in self.words.all():
if word.language_id != self.language_id:
raise ValidationError('One of the words has a false language')
При попытке добавить новое предложение (например, через django admin) я получаю 'Sentence' instance needs to have a primary key value before a many-to-many relationship can be used
. Это означает, что я не могу получить доступ к self.words перед сохранением, но это именно то, что я пытаюсь сделать. Есть ли способ обойти это, чтобы вы могли проверить эту модель? Я действительно хочу напрямую проверить поля модели.
Я нашел много вопросов об этом исключении, но я не смог найти помощь в решении этой проблемы. Буду признателен за любые предложения!
Ответы
Ответ 1
Невозможно выполнить эту проверку в методе модели clean
, но вы можете создать модельную форму, которая может подтвердить выбор words
.
from django import forms
class SentenceForm(forms.ModelForm):
class Meta:
model = Sentence
def clean(self):
"""
Checks that all the words belong to the sentence language.
"""
words = self.cleaned_data.get('words')
language = self.cleaned_data.get('language')
if language and words:
# only check the words if the language is valid
for word in words:
if words.language != language:
raise ValidationError("The word %s has a different language" % word)
return self.cleaned_data
Затем вы можете настроить свой класс администратора модели Sentence
, чтобы использовать свою форму в администраторе Django.
class SentenceAdmin(admin.ModelAdmin):
form = SentenceForm
admin.register(Sentence, SentenceAdmin)
Ответ 2
Вы не можете сделать это из метода clean
модели. Это просто невозможно с тем, как отношения M2M работают в Django. Тем не менее, вы можете выполнить такую проверку в формах, используемых для создания Sentence
, например, в администраторе или форме на вашем сайте.