Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

custom url patterns in Django

I have a website I am trying to build for personal use, and it possesses two id's one for a meeting (where the race is run) and one for the event (the race number). The event id is in the form of "123456_01" and is passed in the model as a primary key for the Event model, as seen below...

class Event(models.Model):
    meeting = models.CharField(max_length=500)
    meetingID = models.ForeignKey(Meeting, on_delete='CASCADE', related_name='races')
    eventID = models.CharField(max_length=300, primary_key=True)
    venue = models.CharField(max_length=600, null=True)
    race_no = models.CharField(max_length=2)
    event_time = models.TimeField()
    status = models.CharField(max_length=100)
    distance = models.CharField(max_length=600)

I currently have the views file set up as follows:

class EventDetailView(DetailView,LoginRequiredMixin):
    context_object_name = 'race_detail'
    template_name = 'event.html'
    model = models.Event
    slug_url_kwarg = 'eventID'

I also have my front end set up so that at present when I click on a certain race, it automatically navigates to the page with the link http://127.0.0.1:8000/app/123456_01/, so that part is working through this config in the HTML:

{% url 'bettingUI:race' eventID=events.eventID %}

the problem I seem to be having is with the configuration of the urls.py file and possibly something I am missing in the views.py file.

my urls.py file is set up as follows :

from django.urls import path, include
from . import views

app_name = 'bettingUI'

urlpatterns = [
    path('',views.DashListView.as_view(),name='dashboard'),
    path('<eventID>/', views.EventDetailView.as_view(), name='race'),   

]

I thought from reading the docs that I need to use a slug because of the '_' character in the ID I am passing in but I am constantly getting an error in the browser stating that it can not resolve keyword 'slug' into the field. Choices are: dro_eventID, dro_meetingID, dro_meetingID_id, event_time, meeting, race_no, runners, status, venue ( **the fields of the model). If I change the urls.py file to the below, I get the same error:

   path('<slug:eventID>/', views.EventDetailView.as_view(), name='race'),

I am a bit lost here so would love some guidance.

Thank you.


I worked it out, the answer is to input <slug:pk>

but now I am getting an error at my dashpage (the page i land at to click through to the race page):

NoReverseMatch at /app/
Reverse for 'race' with keyword arguments '{'eventID': '1216859_01'}' not found. 1 pattern(s) tried: ['app/(?P<pk>[-a-zA-Z0-9_]+)/$']
like image 377
Ben Muller Avatar asked Sep 08 '25 12:09

Ben Muller


1 Answers

So I give it again now the working version:

First you should add a slug field to your Event Model and this will let you use slug, so your model will look like this:

from django.utils.text import slugify

class Event(models.Model):
    meeting = models.CharField(max_length=500)
    meetingID = models.ForeignKey(Meeting, on_delete='CASCADE', related_name='races')
    eventID = models.CharField(max_length=300, primary_key=True)
    venue = models.CharField(max_length=600, null=True)
    race_no = models.CharField(max_length=2)
    event_time = models.TimeField(null=True)
    status = models.CharField(max_length=100, null=True)
    distance = models.CharField(max_length=600, null=True)
    slug = models.SlugField(max_length=50, null=True)

    def save(self, *args, **kwargs):
        self.slug = slugify(self.eventID, allow_unicode=True)
        return super(Event, self).save(*args, **kwargs)

Notice the save() function and in that we added a slugify() method to slugify the eventID field at event savings.

Then your views should look like these:

from .models import Event, Meeting

class EventList(ListView):
    model = Event
    template_name = 'event_list.html'
    context_object_name = 'race_list'    

class EventDetailView(DetailView,LoginRequiredMixin):
    context_object_name = 'race_detail'
    template_name = 'myusers1/event.html' # this could be only event.html if the template is in yourapp/templates/ folder directly
    model = Event
    slug_url_kwarg = 'slug'

Notice in the above view that we now use actually the default slug definition.

I put the listview url under races/ sub-url but you can put it anywhere you want. And in your urls.py you can now use the slug values correctly like:

path('races/<slug:slug>/', views.EventDetailView.as_view(), name='race'),
path('races/', views.EventList.as_view(), name='race_list'),

In my trial app the templates look like the followings: listview template:

{% extends 'myusers1/base.html' %}

{% block content %}

<div class"container">
  <div class="col col-lg-2">
    <h2>Races</h2>
        <ul>
            {% for race in race_list %}
                <div class="col-xs-12 .col-md-8"><li><a href="{% url 'Myusers1:race' slug=race.slug %}"> {{ race.venue }} </a> </li></div>
            {% endfor %}
        </ul>
  </div>
</div>

{% endblock %}

And the detail template looks like this:

{% extends 'myusers1/base.html' %}

{% block content %}

<div class"container">
  <div class="col col-lg-2">

    <h2>Race Details</h2>

            <div class="col-xs-12 .col-md-8"> <h4>Venue name: </h4> {{ race_detail.venue}} </div>
            <div class="col-xs-12 .col-md-8"> <h4>Event ID: </h4> {{ race_detail.eventID }} </div>
            <div class="col-xs-12 .col-md-8"> <h4>Meeting name: </h4> {{ race_detail.meeting }} </div>
            <div class="col-xs-12 .col-md-8"> <h4>Meeting ID: </h4> {{ race_detail.meetingID.id }} </div>

  </div>
</div>

{% endblock %}

And the visual result about how dynamic urls work using the above:

enter image description here

I hope that the above will help you to finalize your app list and details view now. Cheers.

like image 178
Zollie Avatar answered Sep 11 '25 07:09

Zollie