Home Ask Login Register

Developers Planet

Your answer is one click away!

Sebastian Olsen February 2016

How to route DetailView to inherit user and slug

I have a fairly simple DetailView:

class TrackDetails(DetailView):
    model = Track

And in my urls.py:

url(r'^(?P<slug>[-\w]+)/$', TrackDetails.as_view(), name='track-details'),

The model:

class Track(models.Model):


    # Variables

    track_type_choices = [
        ('ORG', 'Original'),
        ('RMX', 'Remix'),
        ('CLB', 'Collab'),
        ('LIV', 'Live'),

    # Model Fields
    user = models.ForeignKey(User, unique=False)
    title = models.CharField(max_length=100)    
    desc = models.TextField(max_length=7500)
    track_type = models.CharField(max_length=3,

    track_type_content = models.CharField(max_length=100,blank=True)
    created = models.TimeField(auto_now=True,auto_now_add=False)

    upload = models.FileField(upload_to=generate_user_folder_tracks,storage=OverwriteStorage(),validators=[is_mp3])
    albumart = models.ImageField(upload_to=generate_user_folder_art,storage=OverwriteStorage(),validators=[is_square_png])
    private = models.BooleanField(default=False)
    downloadable = models.BooleanField(default=False)

    likes = models.ManyToManyField(User, related_name="likes",blank=True)
    dislikes = models.ManyToManyField(User, related_name="dislikes",blank=True)
    plays = models.BigIntegerField(default=0)

    slug = models.SlugField(max_length=50,unique=True)

The model displayed in the view has a "user" field connected to the user model, I want to use this in the url, so that instead of writing "www.domain.com/slug/" I would write "www.domain.com/user/slug" to access the view of the instance.

Additionally, I have extended the User model with a field called "Display_name", I'd like to show this field instead of the username in my template (track_detail.html):



djq February 2016

To access username and slug first pass in the two keywords:

url(r'^/(?P<username>\d+)/(?P<slug>[-\w]+)/$', get_userpage, name='track-details'),

Then check if Track.objects.filter(slug=slug, username=username) returns anything:

def get_userpage(request, username, slug):
   """Render user page"""
   user = User.objects.get(username=username)
   track_song = Track.objects.filter(slug=trackslug, user=user).first() 
   if track_song:
       # return song page for user

      # try to return user
      track_user = Track.objects.filter(user=user).first() 
      if track_user:
          # return user page

   # if nothing returned above 
   # return 404

Previous suggestions:

  • you can you use get_object_or_404(Track, slug=slug) in your view to return the correct response.

  • you could also redirect a user to their unique combination of username and slug using:

    redirect('track-username-slug', username=myusername slug=myslug, permanent=True)

where track-username-slug is your named url

Alasdair February 2016

To include the username in the detail view, you first need to add it to your url patterns.

url(r'^(?P<username>[-\w]+)/(?P<slug>[-\w]+)/$', TrackDetails.as_view(), name='track-details'),

Then, since you are using DetailView, you need to override get_object so that you use the username and slug to fetch the object.

from django.shortcuts imporg get_object_or_404

class TrackDetails(DetailView):
    model = Track

    def get_object(self, queryset=None):
        return get_object_or_404(

Displaying the display_name of the user in the template is a separate problem. If you have a user, you can follow the one to one key backwards to the profile with user.userprofile. Therefore, in your template you can show the display_name with.

{{ object.user.userprofile.display_name }}

Post Status

Asked in February 2016
Viewed 3,801 times
Voted 9
Answered 2 times


Leave an answer

Quote of the day: live life

Devs Planet ®

2014-2016 www.devsplanet.com

Devs Planet © all rights reserved