0

In my Django project I have Products.

You can access products using this url pattern:

example.com/tshirt or example.com/jacket etc.

Moreover, you can view some other pages for those products, i.e.:

example.com/tshirt/details or example.com/jacket/buy

My problem: When I create a new product in my admin interface, the product is deactivated by default (I can activate it later). The reason is that when I create a new product I often don't have all necessary information yet (i.e. price). As long as a product is deactivated all URLs starting with example.com/this-one-product should not be visible for the normal visitor (getting 404 error). Unfortunately, I don't know how to do that.

My goal is that it's visible for the super user or users from the staff. Because it makes sense that they can check that product and see how it looks like when it's rendered. But, as said, it should not be visible for the normal visitor of the webpage.

Now I could of course create if statements in all those views (and check if superuser or from staff), but that does not sound like a elegant solution. Because I would have to add those statements to many different views and that's against DRY and I just don't like this solution.

What would be perfect: A setting to deliver 404 error for all visitors of a product that is deactivated. How is that possible?

Aliquis
  • 2,091
  • 4
  • 21
  • 40
  • you need override you get queryset with your rules, for more help you need show your details view. – Brown Bear Aug 20 '17 at 22:37
  • This seems to be described in the docs [https://docs.djangoproject.com/en/1.11/ref/contrib/admin/actions/](https://docs.djangoproject.com/en/1.11/ref/contrib/admin/actions/) – Simon Hobbs Aug 20 '17 at 22:43
  • 1
    Possible duplicate of [Django is\_staff permission decorator](https://stackoverflow.com/questions/5833184/django-is-staff-permission-decorator) – Paulo Almeida Aug 20 '17 at 23:05

1 Answers1

0

You define two functions which return queryset visible to the request.user's type (staff/non-staff)

I would define it as a queryset method

def staff_visible(self):
  queryset = self.filter(Q(staff_visible=True))
  return queryset

def visible(self):
  queryset = self.filter(is_active=True)
  return queryset

now you could use Product.objects.staff_visible() and so on.

Furthermore you could define two custom Manager class and override get_queryset to use either of above two.

eugene
  • 39,839
  • 68
  • 255
  • 489