我的views.py
中有一些非常简单的观点。
class IndexView(generic.ListView):
template_name = 'voting/index.html'
context_object_name = 'latest_question_list'
def get_queryset(self):
"""
Return the last five published questions (not including those set to be
published in the future).
"""
return Poll.objects.filter(
pub_date__lte=timezone.now()
).order_by('-pub_date')[:5]
class DetailView(generic.DetailView):
model = Poll
template_name = 'voting/detail.html'
context_object_name = 'question'
def get_queryset(self):
"""
Excludes any questions that aren't published yet.
"""
return Poll.objects.filter(pub_date__lte=timezone.now())
class ResultsView(generic.DetailView):
model = Poll
template_name = 'voting/results.html'
context_object_name = 'question'
我还创建了一个model
,我在其中存储了哪些用户被邀请到哪些民意调查以及其他一些数据。
class EligibleVoters(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
poll = models.ForeignKey(Poll, on_delete=models.CASCADE, null=True)
encrypted_keypart = models.BinaryField(max_length=200, blank=True)
decrypted_keypart = models.BinaryField(max_length=200, blank=True)
class Meta:
unique_together = ["user", "poll"]
我想限制未受邀参与民意调查的用户查看这些民意调查。
我认为我想要做的就是每个视图都是这样的,但我不确定这是否是正确的方法。
class DetailView(generic.DetailView):
model = Poll
template_name = 'voting/detail.html'
context_object_name = 'question'
def get_queryset(self):
"""
Excludes any questions that aren't published yet.
"""
if EligibleVoters.objects.filter(poll=Poll.objects.id, user=self.request.user.id).exists():
return Poll.objects.filter(pub_date__lte=timezone.now())
else:
return render('voting/somethingsomething.html')
})
我应该以这种方式限制对特定民意调查的访问吗?此外,上述代码并没有真正起作用并且出现了一些错误,但我不确定是否应该继续尝试以这种方式修复它。
答案 0 :(得分:2)
您应该使用EligibleVoter作为直通字段,将Poll中的多对多字段添加到用户:
eligible_users = models.ManyToManyField('User', through='EligibleVoter')
现在你可以做到:
return Poll.objects.filter(eligible_users=self.request.user, pub_date__lte=timezone.now())
答案 1 :(得分:2)
eligblevoters
get_queryset
不呈现输出,它只生成一个查询集。
尽管如此,我们可以通过添加额外的过滤来限制访问:
class DetailView(generic.DetailView):
model = Poll
template_name = 'voting/detail.html'
context_object_name = 'question'
def get_queryset(self):
return super(DetailView, self).get_queryset().filter
eligiblevoters__user=self.request.user,
pub_date__lte=timezone.now()
)
其他视图中应使用类似的方法。
查询的工作原理如下。通过从ForeignKey
定义EligibleVoters
到User
(名为user
),然后Django反向创建隐式关系:您可以查询使用User.eligblevoters_set
获取相关的EligableVoters
查询集。我们也可以使用elgiblevoters
进行过滤。
因此,我们添加了两个额外的过滤条件:pub_date__lte=timezone.now()
来过滤之前发布的帖子(现在包含在内)和eligiblevoters__user=self.request.user
。这意味着我们添加了至少其中一个相关eligablevoters
应该具有user
self.request.user
(此特定会话的用户)的约束。< / p>
因此,如果没有此类Post
,则我们无法获得Poll
所请求的id
。
我们还可以在找不到对象的情况下呈现页面,例如通过使用.get(..)
修补try
函数 - except
和Http404
,然后呈现特定页面,例如:
from django.http import Http404
class DetailView(generic.DetailView):
model = Poll
template_name = 'voting/detail.html'
context_object_name = 'question'
def get_queryset(self):
return super(DetailView, self).get_queryset().filter
eligiblevoters__user=self.request.user,
pub_date__lte=timezone.now()
)
def get(request, *args, **kwargs):
try:
return super(DetailView, self).get(request, *args, **kwargs)
except Http404:
return render(request, 'app/template_not_found.html', {})
所以在这里我们渲染一个(可能是不同的模板),这里有一个空的上下文,尽管你当然可以使它更高级。