我正在创建一个相当简单的网络应用程序,它允许我对各种项目进行评级(希望用于生成一些机器学习建议)。
我使用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
但是,我正在寻找一种方法来以两种方式过滤这些项目:
我想我需要查询投票表(过滤当前用户)才能这样做。由于我没有“媒体”评级以外的任何内容,我可以忽略通用评级表的“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),如果这很重要的话。
答案 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
有关更好地实现此类功能的性能和/或设计提示仍将受到赞赏!