Reputation: 1372
I have two models : User and Article Each User can create an Article via the selection of one or several Tag.
I am using the following representation in my model :
class User(models.Model):
name = models.CharField(max_length=200, null=False, blank=False, default=None)
articles = models.ManyToManyField(Article, null=True, blank=True, default=None, through='Tag')
class Article(models.Model):
url = models.URLField(unique=True)
class Tag(models.Model):
name = models.CharField(max_length=200, null=False, blank=False, default=None)
article = models.ForeignKey(Article)
user = models.ForeignKey(User)
Now, I can add users and articles separately. Then I can associate a user to an article.
Say I have only <user 1>
and <article 1>
. I create two distinct tags (done via the admin) :
Tag1
<user 1> ---> <article 1>
Tag2
<user 1> ---> <article 1>
I still have only one user, and only one article, but two tags are linking them. When I query user1.article.all() I expect only one article as result.
Expected behavior :
user = User.objects.get(pk=1)
print user.article.all()
[<Article: 1>]
Observed behavior
user = User.objects.get(pk=1)
print user.article.all()
[<Article: 1>, <Article: 1>]
Anyone knows if this is a bug or if I am querying Django (1.7.1 and 1.7.2) in a bad way ? If this is normal, how can I remove the duplicates easily ?
[Edit] Opened a ticket in case it is a bug : https://code.djangoproject.com/ticket/24079#ticket
Upvotes: 1
Views: 817
Reputation: 49012
You need to use .distinct()
. From the docs:
By default, a QuerySet will not eliminate duplicate rows. In practice, this is rarely a problem, because simple queries such as
Blog.objects.all()
don’t introduce the possibility of duplicate result rows. However, if your query spans multiple tables, it’s possible to get duplicate results when a QuerySet is evaluated. That’s when you’d usedistinct()
.
Upvotes: 2