Url logic

30 views
Skip to first unread message

giuliano....@gmail.com

unread,
Dec 15, 2013, 4:20:17 AM12/15/13
to django...@googlegroups.com
 
Hello,
 
I'm wondering how you would you organize the url layout in a following scenario
 
Suppose I've a table of Authors and for each author a list of books.
A book can have only one author, so I link the author with a foreign key.
 
Now I could point to a particular author with a url like this (to show the details)
 
/mylibrary/author/32
 
I wish to put a button to add a new book and would like the CreateView derived class handling the request to collect the author id (32 in this case) so my form would automatically set the foreign key and make it unchangeable from the client browser.
 
Now the questions are:
 
1) would you oranize the url in a way like this?   (notice that 32 is the author id)
/mylibrary/book/32/addnewbook
 
2) how do I extract the slug within my BookNew (derived from CreateNew)?
url(r'^book/(?P<slug>\d+)/addnewbook, BookNew.as_view()),
 
seems not avaliable as in the context/template: {{ slug }}
 
Cheers,
Giulio.
 
 
 

Drew Ferguson

unread,
Dec 15, 2013, 8:22:29 AM12/15/13
to django...@googlegroups.com
Hi

You can get at components passed in the url in views like this

class AuthorView(DetailView):
model = Author

def get_context_data(self, **kwargs):
context = super(AuthorView, self).get_context_data(**kwargs)
slug = self.kwargs['slug']

So if you are adding a book you can do something similar

class BookCreate(CreateView)
model = Book

def get_initial(self):
initials = super(BookCreate, self).get_initial()
initials['author'] = self.kwargs['slug']

and if you want to return to the author after creating the book

def get_success_url(self):
slug = self.kwargs['slug']
return reverse('author', kwargs={'slug': slug})

Although you can build up a complicated url like this

r'^author/(?P<aid>\d+)/book/(?P<pk>\d+)/edit$',
view=BookEdit.as_view(),
name='bookedit'),

and still access the url components like
aid = self.kwargs['aid']
pk = self.kwargs['pk']

it means often over-riding get_queryset, get_context_data, etc just to get
at the components to reconstruct urls so you can navigate between
views and of course the url becomes fragile if you can change the author of
a book or a book has several authors
I prefer to avoid this and edit books under their own url tree like

r'^book/(?P<pk>\d+)/edit$',
view=BookEdit.as_view(),
name='bookedit'),

This keeps the view much simpler.

You can still easily move between the two models or include related
material using "related_names" on the model's ForeignKey

so if in models.Book we had

author = models.ForeignKey('Author', related_name='books')

in your Author templates you can do

{% for book in author.book_set.all %}
{% end for %}

or just

{{ author.book_set.count }}

https://docs.djangoproject.com/en/1.5/topics/db/queries/#backwards-related-objects
--
Drew Ferguson
AFC Commercial
http://www.afccommercial.co.uk

Branko Majic

unread,
Dec 16, 2013, 5:27:53 PM12/16/13
to django...@googlegroups.com
On Sun, 15 Dec 2013 01:20:17 -0800 (PST)
giuliano....@gmail.com wrote:

>
One way to take care of this is to have a URL of
form /mylibrary/book/new?author_id=32. I.e. you'd pass the default
values for author ID via GET parameter, and based on that you'd set-up
the query set for your form widget inside of a view.

I think this is just one possible approach, of course. The thing is,
this way it might be a bit easier to extend the schema for other fields
by adding extra GET parameters, and you'd avoid redundancy and
duplication with URLs (i.e. there's just one and only one URL for adding
books).

Best regards

--
Branko Majic
Jabber: bra...@majic.rs
Please use only Free formats when sending attachments to me.

Бранко Мајић
Џабер: bra...@majic.rs
Молим вас да додатке шаљете искључиво у слободним форматима.
signature.asc
Reply all
Reply to author
Forward
0 new messages