3

I have just completed the Django tutorials, and while excited about learning more, I am by no means proficient. I guess you could say that I don't know enough to be dangerous at this point.

Let's say that I have a database of music. I have an Artist model, an Album model, a Genre model, and a Song model. What I would like to be able to do is display albums (or even artists) based on given filters; so my front-end would display a list of albums and provide a means to filter the list. A "Jazz" link, for instance, would only display Jazz albums. Simple enough.

I can think of a couple ways to accomplish this, but I would like to start out on the right foot...to begin forming "best practice" Django methods. One way I can think of would be to write views...such that /albums/jazz would only display jazz. Another way would be to write model-level methods that filter the albums. Here I get a little fuzzy on how I would actually implement such a filter, however.

Will someone please give me broad overview of how this task is best accomplished?

1 Answer 1

2

Assuming you know how to structure an app within a project (i.e. what the tutorial teaches) you can work along this example with example models.py, urls.py and views.py for your sample app myapp.

Example models.py:

class Genre(models.Model):
    name = models.CharField(unique=True) # set name to be unique
    ...

class Album(models.Model):
    genre = models.ForeignKey(Genre)
    ...

Example urls.py:

urlpatterns = patterns('',
    ...
    url(
        r'^albums/(?P<genre>[-\w]+)/$',
        ListAlbumsByGenreView.as_view(), name='list_albums_by_genre_view'
    ),
    ...
)

Note the genre parameter as the only argument in the URL pattern.

Example views.py using ListView:

from django.shortcuts import get_object_or_404
from django.views.generic.list import ListView

from myapp.models import Album, Genre

class ListAlbumsByGenreView(ListView):

    model = Album

    def get_context_data(self, **kwargs):
        context = super(ListAlbumsByGenreView, self).get_context_data(**kwargs)
        # fetch the genre; if genre not found, an HTTP 404 is returned
        genre = get_object_or_404(Genre, name=kwargs['genre'])
        # filter the albums by genre
        context['albums'] = Album.objects.filter(genre=genre)
        return context

The above ListView puts albums in your HTML template's context; this contains the list of albums filtered by genre.

The individually imported functions used above are all beautifully documented in the Django docs.

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

2 Comments

Thank you very much. The only line I am having trouble understanding is: 'context = super(ListAlbumsByGenreView, self).get_context_data(**kwargs)'
get_context_data is an inherited method of ListView class; you have to call its super parent method so that you initiate the context with any context that the parent function returns. For example, if the ListView sets an page_no in the context, this call ensures this actually happens. Note that this is just an example. In this case I did it simply to follow best practices (and you should do that as well).

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.