Instead of get()
use filter()
and exists()
:
if album.artists.filter(name='Major Lazer').exists():
check_duplicate = True
break
else:
continue
Pergunta
I'm doing some form validation with Django for users adding a music album and its tracks to a database. Two albums of same name can exist as long as they're tied to diff. artists. This way, both artist name Beatles and Beatles Cover Band can both have an album called Hard Days Night in the db.
I've retrieved album objects with the same name called into a list called retrieve_albums
and check each object for its artist using a for loop. The problem is that when I use .get
on the queryset, I get error DoesNotExist: <object> matching query does not exist
, which I say is a sort of descendant error of NameError. So I try putting inside a try
block as shown.
>>> check_duplicate = False
>>> for album in retrieve_albums:
... try:
... if album.artists.get(name='Major Lazer'):
... check_duplicate = True
... break
... except NameError:
... pass
By the way, since these are ManyToManyKeys, I can't just call album.artists(name=artist)
.
Ideally, the logic I'd like to do without try
and except
is:
for album in retrieve_albums:
if album.artists.get(name='Major Lazer'):
check_duplicate = True
break
else:
continue
Using get
throws a DoesNotExist error even just evaluating the if statement - it doesn't even get to the block. I also tried using album.artists.get(name='Major Lazer', None)
but get SyntaxError: non-keyword arg after keyword arg
What's the best way to do this?
EDIT:
models.py for ref.
class Artist(models.Model):
name = models.CharField(max_length=100, null=False, blank=False)
short_bio = models.CharField(max_length=2000, null=False, blank=False)
added = models.DateTimeField(auto_now=True, auto_now_add=False)
updated = models.DateTimeField(auto_now=False, auto_now_add=True)
class Album(models.Model):
name = models.CharField(max_length=150, null=False, blank=False)
artists = models.ManyToManyField(Artist)
active = models.BooleanField(default=True)
slug = models.SlugField(null=True, blank=True)
added = models.DateTimeField(auto_now=True, auto_now_add=False)
updated = models.DateTimeField(auto_now=False, auto_now_add=True)
class Track(models.Model):
name = models.CharField(max_length=200, null=False, blank=False)
albums = models.ManyToManyField(Album)
track_no = models.PositiveSmallIntegerField(null=True, blank=True)
Solução
Instead of get()
use filter()
and exists()
:
if album.artists.filter(name='Major Lazer').exists():
check_duplicate = True
break
else:
continue
Outras dicas
album.artists
is a Django QuerySet
object, not a Python dict
. You need to catch the DoesNotExist
exception instead. You can import it into your current namespace with:
from django.core.exceptions import ObjectDoesNotExist
See the QuerySet API reference.