I have a Django Model where users can create objects and keep them private for a certain period of time.
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()
In my ListView, I want for visitors only the "non-private" objects to appear and for authenticated users the "non-private" objects plus their own private objects. So my Manager looks like this:
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()))
For my ListView this works great. But when I click on an object to get its DetailView, I get a 404 error right on "URL-Level". In my URLs I have:
path('<slug:slug>', MyModelDetailView.as_view(), name='mymodel_detail'),
... and somehow, Django checks already in advance the whole slug against the per Manager allowed slugs, before I have the chance to pass the user in. What is the way to solve my problem? Any help is appreciated. Thanks in advance!
EDIT: My DetailView looks like this:
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)