1

There's a lot of questions worded similarly, but every single one I've seen is somebody trying to get some kind of data through a ManyToMany relationship before saving it. I'm not trying to use the relationship at all before saving, I just want to see if the user put anything there or not.

My model has a ForeignKey field pointing to a parent model, and two ManyToMany fields pointing to other models, but I only want users to be able to use one M2M field or the other, not both. This model is being edited through the admin as an inline on its parent.

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

I only want users to be able to choose from brands or lines, but not both, and I would like to validate this before save and throw a validation error if necessary. My initial attempt was to just do...

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')

...but that throws ValueError: "<ProductSpecialAmount: ProductSpecialAmount object (None)>" needs to have a value for field "id" before this many-to-many relationship can be used.

I get that I can't actually query the related ProductBrand or ProductModel objects before this object is saved, but I don't actually want any data from those objects right now, I just want to know if the user left either of the fields blank or not, and am wondering if that's possible to see at the model level.

GlenVaughan
  • 143
  • 1
  • 3
  • 11

1 Answers1

1

Whether you actually want to use the data from a field or just see if it is blank, the problem is caused by referencing the m2m field in any way before saving the object. I had a similar problem which I fixed using a custom form as per: https://stackoverflow.com/a/7986937/19837155

This might be more difficult when you're using inlines, but it may be the easiest way to solve your problem.

Goodfolk
  • 11
  • 2