0

I am trying to implement multiple URL patterns pointing to one Class Based View in my django 2+ app.

My urls:

path('<slug:slug>', views.OfferDetailView.as_view(), name='show'),
path('<slug:slug>/<str:status>', views.OfferDetailView.as_view(), name='show'),
path('<slug:slug>/<str:status>/<uuid:application>', views.OfferDetailView.as_view(), name='show'),
path('<slug:slug>/<uuid:application>', views.OfferDetailView.as_view(), name='show'),

Let's say that "ABC12" is my slug here. What is my expected behaviour:

  • when user enters /ABC12: view's kwargs status and application are Nones, slug is ABC12
  • when user enters /ABC12/new: view's kwargs status is "new" and application is None, slug is ABC12
  • when user enters /ABC12/new/6eba5dbf-220b-4913-a359-f93fab3153d1: view's kwargs status is "new" and application kwarg is "6eba5dbf-220b-4913-a359-f93fab3153d1", slug is ABC12
  • when user enters /ABC12/6eba5dbf-220b-4913-a359-f93fab3153d1: view's kwargs status is None and application kwarg is "6eba5dbf-220b-4913-a359-f93fab3153d1", slug is ABC12

however, when I type url: /ABC12/6eba5dbf-220b-4913-a359-f93fab3153d1

kwargs are:

{'slug': 'ABC12', 'status': '6eba5dbf-220b-4913-a359-f93fab3153d1'}

(I've expected that there should be not status kwarg, and 'application' kwarg should be "6eba5dbf-220b-4913-a359-f93fab3153d1").

How can I achieve this? I don't want to end up with multiple views.

dease
  • 2,975
  • 13
  • 39
  • 75

1 Answers1

0

This is happening because this '6eba5dbf-220b-4913-a359-f93fab3153d1' uuid is satisfying 2nd pattern of your URL i.e

path('<slug:slug>/<str:status>', views.OfferDetailView.as_view(), name='show'),

One thing you can do to solve it is to rearrange the sequence of URL patterns, keep your last <uuid:application> pattern on 2nd number.

path('<slug:slug>', views.OfferDetailView.as_view(), name='show1'),
# keep this here
path('<slug:slug>/<uuid:application>', views.OfferDetailView.as_view(), name='show2'),
path('<slug:slug>/<str:status>', views.OfferDetailView.as_view(), name='show3'),
path('<slug:slug>/<str:status>/<uuid:application>', views.OfferDetailView.as_view(), name='show4'),

Also don't use same name for url patterns

UPDATE

str - Matches any non-empty string, excluding the path separator, '/'. This is the default if a converter isn’t included in the expression.

So if you are willing to parse uuid you should keep it above from str pattern, if your URL patterns are similar other than arg type

On the other hand, uuid will only parse the string formatted like '6eba5dbf-220b-4913-a359-f93fab3153d1'

uuid - Matches a formatted UUID. To prevent multiple URLs from mapping to the same page, dashes must be included and letters must be lowercase. For example, 075194d3-6885-417e-a8a8-6c931e272f00. Returns a UUID instance.

Read the docs

Satendra
  • 6,755
  • 4
  • 26
  • 46
  • 1
    Why is it satisfying 2nd url pattern? So what is the purpose of argument types in urls, if its UUID not string? EDIT: changing to worked for me, now everything is working just fine – dease Aug 08 '18 at 15:47
  • @dease Check my update, let me know if this fixed your issue – Satendra Aug 08 '18 at 15:58
  • @dease If you want to keep it `str`, you need to rearrange the URL sequence. can you verify this answer? by changing the `str` to `slug` solved for you but this is not the idol solution. – Satendra Aug 08 '18 at 16:26