Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Showing validation error from m2m_changed signal in django admin

I am trying to validate that the variable foo is the same for MyModel and Item before adding it as a m2m. I want to raise a ValidationError in the admin if it is not.

models.py

class Item(models.Model):
    foo = models.CharField(max_length=200)    

class MyModel(models.Model):
    foo = models.CharField(max_length=200)
    items = models.ManyToManyField(Item)

signals.py

@receiver(m2m_changed, sender=MyModel.items.through)
def my_validator(sender, instance, action, pk_set, **kwargs):
    if action == 'pre_add':
        if Item.objects.filter(id__in=pk_set, foo=instance.foo).count() != len(pk_set):
            raise ValidationError({'items': ["Foo doesn't match"]})

Is there a way for the ValidationError to show up properly in the admin and not as a 500 error.

I wasn't able to come up with a solution to use MyModel's clean method to validate the same value of foo. Any advice is appreciated.

like image 986
Maxim Avatar asked Oct 18 '25 16:10

Maxim


1 Answers

Create a form class with clean method and modify your admin class to use the form. Read this:

Like:

@admin.register(MyModel)
class MyModelAdmin(admin.ModelAdmin):
    search_fields = ('foo', 'items__foo')
    list_display = ('foo', 'items__foo')
    form = MyModelForm


class MyModelForm(forms.ModelForm):

    def clean(self):
        """
        This is the function that can be used to 
        validate your model data from admin
        """
        super(MyModelForm, self).clean()
        foo = self.cleaned_data.get('foo')
        pk_set = Item.objects.all().values_list("id")

        # The logic you were trying to filter..
        if Item.objects.filter(id__in=pk_set).count() != len(pk_set):
            raise ValidationError({'items': ["Foo doesn't match"]})
like image 94
Nagaraj Tantri Avatar answered Oct 21 '25 04:10

Nagaraj Tantri



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!