Reputation: 79
My issue:
I'm trying to add some models to my database through the admin path on my django project, but this error keeps popping up when I try to create an instance of my model. The clean
function exists to ensure that each Pokemon model can only have up to 2 types selected from a list of all possible types.
My code:
from django.db import models
from django.core.validators import MinValueValidator as min, MaxValueValidator as max
from django.core.exceptions import ValidationError
class PokeType(models.Model):
poke_type = models.CharField(max_length=15)
def __str__(self):
return self.poke_type
#Current generation of games for gen_added field
gen = 8
class Pokemon(models.Model):
poke_name = models.CharField(max_length=30)
poke_type = models.ManyToManyField(PokeType, blank=True, null=True)
evolves_from = False
evolves_into = False
gen_added = models.PositiveIntegerField(validators=[min(1), max(gen)])
def clean(self):
#Allow max of 2 poke_types to be selected
if self.poke_type.count() > 2:
raise ValidationError('A Pokemon has a maximum of two types.')
class Meta:
verbose_name_plural = 'Pokemon'
abstract = True
class CustomPokemon(Pokemon):
name = models.CharField(max_length=30)
level = models.PositiveIntegerField(blank=True, null=True)
def __str__(self):
return self.name
What I (kind of) know:
Based on what I've seen from other people asking this question, I need to save the instance of my model before I can use the many-to-many relationship in the clean
function. Also, I do not get the error when my clean
function is commented out, so I've narrowed the issue down to that portion of the code.
What I've tried:
I thought that changing my if statement to check for the presence of the poke_type
variable would help - i.e.
def clean(self):
#Allow max of 2 poke_types to be selected
if self.poke_type and self.poke_type.count() > 2:
raise ValidationError('A Pokemon has a maximum of two types.')
but the error is still raised. As I noted above, removing that function also allows me to proceed without raising that specific error, but breaks my ability to limit the max number of types selectable.
Next, I tried creating a save
function to save the model and then give the model the poke_type
attribute after that:
def save(self):
self.save()
self.poke_type = models.ManyToManyField(PokeType, blank=True, null=True)
Is there a way to save the instance of the model as it's being added through the admin site or is that not possible?
Upvotes: 1
Views: 47
Reputation: 1394
Make use of the m2m_changed
signal instead
def poke_type_changed(sender, **kwargs):
if kwargs['instance'].poke_type.count() > 2:
raise ValidationError('A Pokemon has a maximum of two types.')
m2m_changed.connect(poke_type_changed, sender=Pokemon.poke_type.through)
Upvotes: 1