I think you should inspect the data during form submission. Try putting this overloaded clean method into the form and than the form goes into the ModelAdmin definition for your Paper model.
# admin.py
from django.contrib import admin
from django import forms
from django.core.exceptions import ValidationError
from .models import Paper
class PaperForm(forms.ModelForm):
class Meta:
model = Paper
def clean(self):
topic = self.cleaned_data.get('topic')
if topic.count() > 4:
raise ValidationError("To many topics!")
return self.cleaned_data
class PaperAdmin(admin.ModelAdmin):
form = PaperForm
admin.register(Paper, PaperAdmin)
Also it is not the best way to define related_name. related_name is supposed to help you refer back to the model from it's relation. Do it like this:
# in your model
topics = models.ManyToManyField('Topic', related_name='papers', blank=True)
# shell
paper = Paper.objects.order_by('?')[0] # get random object
paper.topics.all() # and access it's topics
topic = Topic.objects.order_by('?')[0] # now get random topic
topic.papers.all() # and get it's papers using related_name!
It's better than topic.topic+.all()
right? I'm not even sure if it'd work.