4

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_]+)/$']
2
  • I think it should be <slug:eventID> Commented Feb 8, 2019 at 20:57
  • nah, that doesn't work Commented Feb 8, 2019 at 21:07

2 Answers 2

2

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.

Sign up to request clarification or add additional context in comments.

1 Comment

The video is a great add-on (+1).
1

I think I found a solution here try this:

url.py:

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

Now you can simple get the instance of Event in your EventDetailView generic view by using get_object method like this:

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

     def get_object(self):          
         e1 = Event.objects.get(eventID=self.kwargs['eventID'])
         print (e1.eventID) # or e1.pk gives: 123456_01
         return e1

You can also change your eventID from CharField to SlugField. And still have it working.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.