Django: Проверять на уровне модели, есть ли что-нибудь в поле ManyToMany перед сохранением
Здесь много вопросов, сформулированных похожим образом, но каждый из них, который я видел, связан с тем, что кто-то пытается получить какие-то данные через отношение ManyToMany перед сохранением. Я не пытаюсь использовать отношения вообще до сохранения, я просто хочу увидеть, поместил ли пользователь любое туда или нет.
В моей модели есть поле ForeignKey, указывающее на родительскую модель, и два поля ManyToMany, указывающие на другие модели, но я хочу, чтобы пользователи могли использовать только одно поле M2M или другое, а не оба. Эта модель редактируется через админку как инлайн на родительской модели.
models.py
class ProductSpecial(models.Model):
# name, slug, image, etc
class ProductSpecialAmount(models.Model):
special = models.ForeignKey(ProductSpecial, related_name='amounts', on_delete=models.CASCADE)
amount = models.IntegerField()
brands = models.ManyToManyField(ProductBrand, related_name='specials', blank=True)
lines = models.ManyToManyField(ProductLine, related_name='specials', blank=True)
admin.py
class ProductSpecialAmountInline(admin.StackedInline):
model = ProductSpecialAmount
# fieldsets, etc
@admin.register(ProductSpecial)
class ProductSpecialAdmin(admin.ModelAdmin):
inlines = [ProductSpecialAmountInline]
# fieldsets, etc
Я хочу, чтобы пользователи могли выбирать только бренды или линии, но не оба, и я хотел бы проверить это перед сохранением и при необходимости выдать ошибку проверки. Моя первоначальная попытка заключалась в том, чтобы просто сделать...
class ProductSpecialAmount(models.Model):
# ...
def clean(self):
if self.brands and self.lines:
raise ValidationError('Please choose either brands or lines, not both', code='invalid')
... но это бросает ValueError: "<ProductSpecialAmount: ProductSpecialAmount object (None)>" needs to have a value for field "id" before this many-to-many relationship can be used.
Я понимаю, что я не могу запросить связанные объекты ProductBrand или ProductModel до сохранения этого объекта, но мне сейчас не нужны данные из этих объектов, я просто хочу знать, оставил ли пользователь пустое поле или нет, и мне интересно, можно ли это увидеть на уровне модели.
Независимо от того, хотите ли вы на самом деле использовать данные из поля или просто посмотреть, пустое ли оно, проблема вызвана тем, что вы ссылаетесь на поле m2m любым способом до сохранения объекта. У меня была похожая проблема, которую я решил с помощью пользовательской формы, как показано ниже: https://stackoverflow.com/a/7986937/19837155
Это может быть сложнее, если вы используете вставки, но это может быть самый простой способ решить вашу проблему.