Django查询,如果一个表中的id在另一个表中,则排除结果

时间:2016-03-27 19:42:43

标签: python django

我正在尝试创建一个Django查询,其结果是Item表中的所有条目,其中在给定用户的Seen表中没有表项的条目。

我的Django模型看起来像这样:

from django.db import models
from django.contrib.auth.models import User

# The keywords that can be associated with an item (e.g. Animals, Scenery, Buildings, Art, ...)
class Keyword(models.Model):
    name = models.CharField(max_length=30)

    # This needed to show the name and not the text 'keyword object' on the Admin page
    def __str__(self):
        return format(self.name)

# Items. E.g. Vines, YouTube, Vimeo, Photo...
class Item(models.Model):

    ITEM_TYPES = (
        ('V', 'Vine'),
        ('Y', 'YouTube'),
        ('P', 'Photo'),         # Photo is stored by us on a CDN somewhere
        ('F', 'Flickr'),
        ('I', 'Instagram'),
        ('D', 'DeviantArt'),
        ('5', '500px'),
    )
    owner           = models.ForeignKey(User, on_delete=models.CASCADE)     # Id of user who owns the item
    url             = models.CharField(max_length=250, default='')          # URL of where item resides (e.g. Vine or YouTube url)
    item_type       = models.CharField(max_length=1, choices=ITEM_TYPES)    # Type of item (e.g. Vine|YoutTube|Instagram|etc.)
    keywords        = models.ManyToManyField(Keyword, related_name='keywords')
                                                                            # E.g. Art, Travel, Food, etc.
    credits_applied = models.IntegerField(default=10, help_text='Total number of credits applied to this item including any given by VeeU admin')
                                                                            # Records the total number of credits applied to the Item
    credits_left    = models.IntegerField(default=10, help_text='The number of credits still remaining to show the item')
                                                                            # Number of credits left (goes down each time item is viewed
    credits_gifted  = models.IntegerField(default=0, help_text='The number of credits this item has been gifted by other users')
                                                                            # Number of credits users have gifted to this item
    date_added      = models.DateTimeField(auto_now_add=True)               # When item was added
    active          = models.BooleanField(default=True, help_text='If you mark this item inactive please say why in the comment field. E.g. "Inapproriate content"')
                                                                            # True if item is available for showing
    comment         = models.CharField(max_length=100, blank=True)          # Comment to be applied if item is inactive to say why

    # Add defs here for model related functions

    # This to allow url to be a clickable link
    def item_url(self):
        return u'<a href="%s">%s</a>' % (self.url, self.url)
    item_url.allow_tags = True

    def __str__(self):
        return '%s: %s' % (self.owner, self.url)

# Record of which items have been viewed, when, and whether they were liked or not
class Seen(models.Model):
    item_id         = models.ForeignKey(Item, on_delete=models.CASCADE)     # id of the item that has been seen
    user_id         = models.ForeignKey(User, on_delete=models.CASCADE)     # id of user who viewed it
    date_seen       = models.DateTimeField(auto_now_add=True)               # When item was viewed
    liked           = models.BooleanField(help_text='If the item was liked this is set to true')
                                                                            # Flag True if item was liked

    # Add defs here for model related functions

我认为我需要使用的查询如下所示:

Item.objects.exclude(
    seen=Seen.objects.filter(
        user_id=23,
        item_id=<id of item from Item table>,
    ),
)

我无法解决的是放置什么,以便将Item表中的每个项目与Seen表中相同项目ID的条目进行比较。

1 个答案:

答案 0 :(得分:1)

通过访问视图中的request对象,您可以从Seen表中获取当前用户的item_id列表,并使用Django&#39; s in进行过滤操作

unseen_items = Item.objects.exclude(
    pk__in=Seen.objects.filter(user_id=request.user).values_list(
        'item_id', flat=True
    )
)

有关inhere的信息,请参阅here了解有关values_list的信息。