使用当前用户ID的Django通用列表视图过滤器

时间:2015-03-05 16:31:04

标签: jquery django

我正在创建一个相当简单的网络应用程序,它允许我对各种项目进行评级(希望用于生成一些机器学习建议)。

我使用Django-ratings获得了5星评级,但是我在为“评分项目”创建新视图时遇到了困难。更具体地说:我在尝试创建“未评级项目”视图和“之前评级项目”视图时遇到困难。

djangoratings的工作原理是使用以下模型来管理投票:

class Vote(models.Model):
    content_type    = models.ForeignKey(ContentType, related_name="votes")
    object_id       = models.PositiveIntegerField()
    key             = models.CharField(max_length=32)
    score           = models.IntegerField()
    user            = models.ForeignKey(settings.AUTH_USER_MODEL, blank=True, null=True, related_name="votes")
    ip_address      = models.IPAddressField()
    cookie          = models.CharField(max_length=32, blank=True, null=True)
    date_added      = models.DateTimeField(default=now, editable=False)
    date_changed    = models.DateTimeField(default=now, editable=False)

class ContentType(models.Model):
    name = models.CharField(max_length=100)
    app_label = models.CharField(max_length=100)
    model = models.CharField(_('python model class name'), max_length=100)
    objects = ContentTypeManager()

我评价的项目(models.py):

class Media(models.Model):
    id = models.AutoField(primary_key=True)
    url = models.CharField(unique=True, max_length=100)
    last_updated = models.DateTimeField(blank=True, null=True)
    ...
    rating = RatingField(range=5, can_change_vote=True, allow_delete=True)  # 5 possible rating values, 1-5
    class Meta:
        verbose_name_plural = "Media"

以下视图通过分页并允许我对每个项目进行评分来实现可爱:

class MediaListView(LoginRequiredMixin, ListView):
    queryset = Media.objects.all()
    template_name = 'myMedia/media_list.html'
    paginate_by = 10

但是,我正在寻找一种方法来以两种方式过滤这些项目:

  • 仅检索按评级日期(DESC)排序的评分视图
  • 仅检索未评级的视图,而不是(但可能稍后!)已订购。

我想我需要查询投票表(过滤当前用户)才能这样做。由于我没有“媒体”评级以外的任何内容,我可以忽略通用评级表的“content_type”方面(它负责评估不同类型的模型)。

我在与识别当前用户相关的问题中经常提到request.user。但是,我在尝试这样做时收到'NameError:name'请求'未定义'错误:

#views.py
class MediaListView(LoginRequiredMixin, ListView):
    queryset = Media.objects.all()
    template_name = 'myMedia/media_list.html'
    paginate_by = 10

class MediaListView_VotesByUser(LoginRequiredMixin, ListView):
    User = request.user
    voted_ids = Vote.objects.filter(user=User).values('object_id', flat=True) # Obtain the IDs for voted items.
    queryset = Media.objects.filter(id__in=voted_ids])
    paginate_by = 10

class MediaListView_Unrated(LoginRequiredMixin, ListView):
    User = request.user
    voted_ids = Vote.objects.filter(user=User).values('object_id', flat=True) # Obtain the IDs for voted items.
    queryset = Media.objects.exclude(id__in=voted_ids])
    paginate_by = 10


# urls.py
urlpatterns = patterns('',
    url(
        regex=r'^$',
        view=views.MediaListView.as_view(),
        name='media'),
    url(r'^rate/(?P<object_id>\d+)/(?P<score>\d+)/', AddRatingFromModel(), {
        'app_label': 'myMedia',
        'model': 'media',
        'field_name': 'rating',
    }),
    url(
        regex=r'^myVotes',
        view=views.MediaListView_VotesByUser.as_view(),
        name='UserVotedOn'),
    url(
        regex=r'^unrated',
        view=views.MediaListView_Unrated.as_view(),
        name='UnratedMedia')

)

此外,我不太确定我正朝着正确的方向前进。我是否需要单独的视图或扩展现有视图?任何有关如何创建这些视图的帮助或提示将不胜感激。我正在使用Django 1.7(使用MySQL),如果这很重要的话。

1 个答案:

答案 0 :(得分:0)

好的,所以在谷歌搜索我的问题标题时我实际上stumbled(!)回答了这个问题,请注意我已经谷歌了很长一段时间!我想是时候再次浏览所有文档了!

  

Django文档:正如您所看到的,在查询集选择中添加更多逻辑非常容易;如果我们想要,我们可以使用self.request.user来过滤使用当前用户或其他更复杂的逻辑。

以下视图返回我的所有投票:

class MediaListView_VotesByUser(LoginRequiredMixin, ListView):
    def get_queryset(self):
        voted_ids = Vote.objects.filter(user=self.request.user).values_list('object_id', flat=True)
        return Media.objects.filter(id__in=voted_ids)
    paginate_by = 10

以下内容将返回未评级的内容。

class MediaListView_Unrated(LoginRequiredMixin, ListView):
    def get_queryset(self):
        voted_ids = Vote.objects.filter(user=self.request.user).values_list('object_id', flat=True)
        return Media.objects.exclude(id__in=voted_ids)
    paginate_by = 10

有关更好地实现此类功能的性能和/或设计提示仍将受到赞赏!