1

Ich versuche zu validieren, dass die Variable foo das gleiche für MyModel und Item ist, bevor Sie es als m2m hinzufügen. Ich möchte einen ValidationError im Admin auslösen, wenn dies nicht der Fall ist.Zeige Validierungsfehler von m2m_changed Signal in Django Admin

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"]}) 

Gibt es eine Möglichkeit für die Validation richtig im Admin zu zeigen und nicht als 500 Fehler.

Ich war nicht in der Lage, eine Lösung zu finden, um MyModels clean-Methode zu verwenden, um den gleichen Wert von foo zu validieren. Jeder Rat wird geschätzt.

Antwort

1

Erstellen Sie eine form Klasse mit clean Methode und ändern Sie Ihre Admin-Klasse, um das Formular zu verwenden. Lesen 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"]}) 
+0

Thank you! Das Erstellen eines ModelForms und das Validieren durch ihn haben den Trick gemacht. Ich habe pk_set jedoch auf self.cleaned_data.get ("items") gesetzt. Nicht sicher, warum Sie Item.objects.all() verwenden. Danke noch einmal!! – Maxim

+0

@Maxim Ich war mir nicht bewusst, was genau pk_set Sie speichern und verwenden wollte, also dachte, es wäre 'pk' Werte von Item-Tabellen und so' Item.object.all() '. Wie auch immer, Sie sind willkommen :) –

+0

keine Sorge, die eigentliche Validierungslogik ist nicht wirklich relevant. Ich schätze deine Hilfe sehr. Sparte mir einen guten Teil der Zeit! Prost – Maxim