我有一个Django模型,用户可以在其中创建对象并在一定时间内保持它们的私有性。
class MyModel(models.Model):
creator = models.ForeignKey(User, null=True, on_delete=models.SET_NULL)
private_until = models.DateField(null=True, default=None, blank=True)
objects = MyModelManager()
在我的ListView中,我只希望访问者使用";非私人";对象出现,并且对于经过验证的用户;非私人";对象加上它们自己的私有对象。所以我的经理是这样的:
class MyModelManager(models.Manager):
def include_his_private(self, user):
if user.is_authenticated:
include_his_private = super().get_queryset().filter(~Q(private_until__gt=datetime.date.today()))
include_his_private |= super().get_queryset().filter(Q(creator=user))
return include_his_private
else:
return super().get_queryset().filter(~Q(private_until__gt=datetime.date.today()))
def get_queryset(self):
return super().get_queryset().filter(~Q(private_until__gt=datetime.date.today()))
对于我的ListView
来说,这非常有效。但是当我点击一个对象以获得它的DetailView
时,我在"上得到404错误;URL级别";。在我的URL中,我有:
path('<slug:slug>', MyModelDetailView.as_view(), name='mymodel_detail'),
不知怎么的,Django在我有机会把用户传进来之前,已经提前检查了整个slug与每个Manager允许的slug。解决我的问题的方法是什么?感谢您的帮助。提前感谢!
编辑:我的详细信息视图如下:
class MyModelDetailView(DetailView):
model = MyModel
template_name = 'mymodel_detail.html'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
slug = self.kwargs['slug']
if self.request.user.is_authenticated:
obj = MyModel.objects.include_his_private(self.request.user).get(slug=slug)
else:
obj = MyModel.objects.get(slug=slug)
ADetailView
[Django-doc]将使用.get_queryset(…)
Django-dok]来获取查询集,在.get_object(…)
方法[Django-dc]中,如果路径包含这样的URL参数,它将自动过滤pk
和/或slug
。因此,这是在运行get_context_data
中的自定义逻辑之前完成的。
因此,您应该覆盖get_queryset
方法:
class MyModelDetailView(DetailView):
model = MyModel
template_name = 'mymodel_detail.html'
defget_queryset(self, *args, **kwargs):
return MyModel.objects.include_his_private(
self.request.user
)