Django `The current path, detail/PayPal, matched the last one` error

I'm using Django's DetailView to display detailed information in my web app. I've set up a Processor model with a name and a slug field, and I'm using the slug field in the URL pattern and the DetailView. However, I'm running into an issue where the DetailView is not able to find the Processor object if the capitalization of the URL slug doesn't exactly match the slug field in the database.

For example if I visit localhost:8000/detail/paypal I get the following error:

Using the URLconf ... Django tried these URL patterns, in this order:

...
detail/<slug:slug> [name='processor_detail']
The current path, detail/PayPal, matched the last one.

In addition the url I entered in the url field changes to localhost:8000/detail/PayPal, capitalizing the letters.

Finally, the url only works if I first visit it by clicking on a link to it from another page. After that it works perfectly normally whether I go incognito mode or not and no matter the capitalization I use in the slug. But if I go incognito mode and visit the url directly(ie, after not having visit it by clicking on a link to it from another page) it doesn't load at all whether I capitalize the slug or not. I hope you can understand my point.

Here is my code:

views.py:

class ProcessorDetailView(DetailView):
    model = Processor
    template_name = 'finder/processor_detail.html'
    slug_field = 'slug'  # Tell DetailView to use the `slug` model field as the DetailView slug
    slug_url_kwarg = 'slug'  # Match the URL parameter name

models.py:

class Processor(models.Model): #the newly created database model and below are the fields

    name = models.CharField(max_length=250, blank=True, null=True) #textField used for larger strings, CharField, smaller
    slug = models.SlugField(max_length=250, blank=True)
...
    def __str__(self): #displays some of the template information instead of 'Processot object'
        if self.name:
            return self.name[0:20]
        else:
            return '--no processor name listed--'
    def get_absolute_url(self): # new
        return reverse("processor_detail", args=[str(self.name)])

    def save(self, *args, **kwargs): #`save` model a certain way(detailed in rest of function below)
        if not self.slug: #if there is no value in `slug` field then...
            self.slug = slugify(self.name) #...save a slugified `name` field value as the value in `slug` field
        super().save(*args, **kwargs)

urls.py:

path("detail/<slug:slug>", views.ProcessorDetailView.as_view(), name='processor_detail')

If I follow a link on a separate template to the the problem url using <a href="{%url 'processor_detail' processor.slug%}" class="details-link"> Details → </a>, for example, it works perfectly fine afterward.

when you're using a url, django uses your model's get_absolute_url to retrieve the right object, which returns the name field. but you asked your view to use slug instead so it breaks. just return slug in your get_absolute_url and it should work

    def get_absolute_url(self): # new
        return reverse("processor_detail", args=[str(self.slug)])
Вернуться на верх