Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to do a DetailView in django 1.3?

I'm currently learning how to use the class-based views in django 1.3. I'm trying to update an application to use them, but I still don't uderstand very well how they work (and I read the entire class-based views reference like two or three times EVERY day).

To the question, I have an space index page that needs some extra context data, the url parameter is a name (no pk, and that can't be changed, it's the expected behaviour) and the users that don't have that space selected in their profiles can't enter it.

My function-based code (working fine):

def view_space_index(request, space_name):

    place = get_object_or_404(Space, url=space_name)

    extra_context = {
        'entities': Entity.objects.filter(space=place.id),
        'documents': Document.objects.filter(space=place.id),
        'proposals': Proposal.objects.filter(space=place.id).order_by('-pub_date'),
        'publication': Post.objects.filter(post_space=place.id).order_by('-post_pubdate'),
    }

    for i in request.user.profile.spaces.all():
        if i.url == space_name:
            return object_detail(request,
                                 queryset = Space.objects.all(),
                                 object_id = place.id,
                                 template_name = 'spaces/space_index.html',
                                 template_object_name = 'get_place',
                                 extra_context = extra_context,
                                )

    return render_to_response('not_allowed.html', {'get_place': place},
                              context_instance=RequestContext(request))

My class-based view (not working, and no idea how to continue):

class ViewSpaceIndex(DetailView):

    # Gets all the objects in a model
    queryset = Space.objects.all()

    # Get the url parameter intead of matching the PK
    slug_field = 'space_name'

    # Defines the context name in the template
    context_object_name = 'get_place'

    # Template to render
    template_name = 'spaces/space_index.html'

    def get_object(self):
        return get_object_or_404(Space, url=slug_field)

    # Get extra context data
    def get_context_data(self, **kwargs):
        context = super(ViewSpaceIndex, self).get_context_data(**kwargs)
        place = self.get_object()
        context['entities'] = Entity.objects.filter(space=place.id)
        context['documents'] = Document.objects.filter(space=place.id)
        context['proposals'] = Proposal.objects.filter(space=place.id).order_by('-pub_date')
        context['publication'] = Post.objects.filter(post_space=place.id).order_by('-post_pubdate')
        return context

urls.py

from e_cidadania.apps.spaces.views import GoToSpace, ViewSpaceIndex
urlpatterns = patterns('',
    (r'^(?P<space_name>\w+)/', ViewSpaceIndex.as_view()),
)

What am I missing for the DetailView to work?

like image 373
CastleDweller Avatar asked May 15 '11 13:05

CastleDweller


1 Answers

The only problem I see in your code is that your url's slug parameter is named 'space_name' instead of 'slug'. The view's slug_field attribute refers to the model field that will be used for slug lookup, not the url capture name. In the url, you must name the parameter 'slug' (or 'pk', when it's used instead).

Also, if you're defining a get_object method, you don't need the attributes queryset, model or slug_field, unless you use them in your get_object or somewhere else.

In the case above, you could either use your get_object as you wrote or define the following, only:

model = Space
slug_field = 'space_name'
like image 174
emyller Avatar answered Sep 22 '22 23:09

emyller