0

My url is structured in this way:

example.com/category/subcategory/name

Right now I'm using a DetailView and it detects the url when I write it but it resolves positively to any address that includes the right name because that name is unique so what I need to check is that the name corresponds to the subcategory and this subcategory corresponds to the main category.

For example my desired url is:

http://example.com/animal/cat/garfield

It resolves alright with a 200 code. However, when I write:

http://example.com/insect/cat/garfield

It also resolves as a 200 instead of a 404.

How do I check those parameters in my view?

My urls.py

path('<str:category>/<str:subcategory>/<str:slug>', views.AnimalDetailView.as_view(), name="animal_detail") 

My view:

class AnimalDetailView(DetailView):
    model = Animal

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['now'] = timezone.now()
        return context
ffuentes
  • 1,042
  • 5
  • 16
  • 36

2 Answers2

0

I think your URL should end with a /. Refer https://docs.djangoproject.com/en/2.1/topics/http/urls/

path('<str:category>/<str:subcategory>/<str:slug>/', views.AnimalDetailView.as_view(), name="animal_detail").

All parameters passed through URL will get using kwargs. If you want access parameters in your view you can use the following approaches 1)

class Test(DetailView):
    def get(self, request, **kwargs):
        subcategory = kwargs['subcategory']
        category = kwargs['category']

2)

class Test(DetailView):
    def get(self, request, category, subcategory, .. ):
        # category contains value of category

The first method is preferred approach.

a_k_v
  • 1,558
  • 7
  • 18
0

What you can do is that, in get_object method, put the constrain yourself by overriding it. For example:

class AnimalDetailView(DetailView):
     ...
     def get_object(self):
         category = self.kwargs.get('category')
         subcategory = self.kwargs.get('subcategory')
         slug = self.kwargs.get('slug')
         animal = Animal.objects.filter(category=category, subcategory=subcategory, slug=slug)
         if animal.exists():
              return super(AnimalDetailView, self).get_object()
         else: 
              Http404("Animal not found")
ruddra
  • 50,746
  • 7
  • 78
  • 101
  • It's throwing a ValueError, it tries to compare the word with an int value. – ffuentes Oct 29 '18 at 04:37
  • writing category__slug it seems to work but when it doesn't find anything it still gets an object so it never throws a 404, rather an empty view. – ffuentes Oct 29 '18 at 04:41
  • means you have an Animal object for /insect/cat/garfield somewhere. Can you share your Category, SubCategory and Animal Model please? – ruddra Oct 29 '18 at 04:55