On Thu, Feb 25, 2016 at 12:45 PM, Malik Rumi <malik.a.r...@gmail.com> wrote:

>
> Assuming it can be done, what is the proper way to namespace two models in
> the same app, where both use slugs in the url but have different views and
> templates?
>
> In the docs,
> https://docs.djangoproject.com/en/1.9/topics/http/urls/#url-namespaces,
> it talks about how to do this, but it always refers to 'applications'
> rather than 'models'.
>

That's because models are only a portion of the functionality of the
framework, and usually each app has multiple models associated with it.
URL's can and often do point to views that don't reference models at all.
Part of the philosophy of Django is loose-coupling of URL's and models (and
every other function of Django, as much as possible).

Normally the URL layout would match the intended application:

fruit/apple/
fruit/bananna/

Where you want to use something like:

apple/
bananna/

This isn't a technical restriction that you are dealing with, it is a
design issue. What if you wanted to list all of the fruit available?

#App based
fruit/ #list all fruit

#Model based
fruit/

However, now you've hit an inconsistency with your URL's and models, since
you probably don't have a concrete model named Fruit.

You can design your URL's however you like, just some food for thought.


> So can I do:
>
> *urls.py*
>
> url(r'^model1/', include('app.urls', appview4model1,
> namespace='app.model1')
>
> url(r'^model2/', include('app.urls', appview4model2,
> namespace='app.model2')
>
>
Sure, although I'm not sure if those namespace strings are valid. I use
dashes, and in this case i would just use 'model1' and 'model2'.


>
>
> *app.urls.py <http://app.urls.py>*
>
> app_name = "app.model1"
>
> urlpatterns [ ....]
>
> app_name = "app.model2"
>
> urlpatterns [ ....]
>
>
> Frankly, I want the shortest urls possible, so if there was a way to do
> this without putting 'model1' or 'model2' in the url, that would be great,
> but I'm not seeing a way around it - assuming the app_name = 'app.model1'
> thing even works.
>

If that's the case, use something like a letter and the PK of the object:
url(r'a/(?P<pk>\d+)/')

Short URL's are a great thing to have, but don't twist yourself into a
pretzel to attain them. Ultimately there are only marginal benefits. It's
means you need to simplify your URL structure, and you can already see what
kind of complication that simplification brings...


>
> Another option I thought of but don't know if possible:
>
> try url(r'^(?P<slug>) )
> except url(r'^modelname(?P<slug>) )
>
> I've never seen anything like that, though. If it did work, I doubt it
> would fit inside urlpatterns[ ], but maybe I could put it after?
>
> Or I could hack the code that handles url name collisions (once I find it)
>
>
There's no practical limit to what a url() tag can contain. URL's can be
thousands of characters long. If your models have a slug attached to them,
you can just use the slug at the top level of the URL structure. It will
likely incur a lookup for each type of model though, and you would need
some extra checking when creating/updating models to ensure that the slugs
are unique between the two. There are various tricks on how to do that
(usually in the save() method of your models) or a related table that keeps
a list of slugs used for both models with uniqueness enforced (maybe even a
GenericForeignKey). Your URL/view can also accept a slug and perform a
lookup against ModelA, and if it doesn't find anything, look again via
ModelB. This is slightly more challenging with a CBV, but is entirely
possible.

Using the bare slug at the top level also hampers your ability to generate
URL's elsewhere due to the overlap with other keywords (although still
possible if you are careful). Technically, keywords like 'contact' are
considered valid slugs, and may incur a lookup against ModelA/B when in
fact you wanted the user to see the contact page.

This method is exactly how URL shorteners work. The system provides the
slug/hash correlated to the real URL in the database, and the shortener
system redirects based on the matching real URL found for the hash.

Unless there is a business requirement for it, I would recommend for your
own sanity each model would live in its own namespace so that wouldn't have
to worry about overlapping slugs, etc.

You should also have a look at app namepaces vs. instance namespaces:
https://docs.djangoproject.com/en/1.9/topics/http/urls/#url-namespaces-and-included-urlconfs

-James

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-users+unsubscr...@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-users/CA%2Be%2BciVo739FURrsFMWyTc9o_Vd%2BYb%2BFZEjJZiVMJP4qWGawWQ%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to