How do I make custom URLs using django? - python

Right now my urls.py file looks like so:
re_path(r'^product-offers/(?P<product_item_id>[-\w]+)$', views.ProductOffersListView.as_view(),
This takes a user to the page: www.shop.com/product/1234
However, is there any way to display the URL with the title (even if that URL doesn't change the dispatching). I want the URL to look like this:
www.shop.com/product/1234/toy-truck
The "toy-truck" part doesn't have to do anything, but it looks professional and would be nice to have.

You can add a slug to your model
Slug is a newspaper term. A slug is a short label for something, containing only letters, numbers, underscores or hyphens. They’re generally used in URLs
https://docs.djangoproject.com/en/2.1/ref/models/fields/#slugfield
Then add it to the url and pass it together with the item id when you call the url
re_path(r'^product-offers/(?P<product_item_id>[0-9]+/(?P<product_item_slug>[\w-]+)/$

Related

Can a empty string be passed in the url in django?

I am working on a django project which have a posts page. I have its url as follows:
path('posts/<str:sort>', views.posts, name='posts'),
and this is what its view looks like:
def posts(request,sort)
b=""
if b=="time":
posts=Post.objects.all().order_by(b)
else:
posts=Post.objects.all()
return render(request,posts.html,{'posts':posts})
Now what I want is that if there is nothing passed as sort in the url or the url is like : /posts/ I want to display all posts but if the parameter is 'time' then I want to order_by as in my view. But currently if nothing is passed in url for sort then I get the error that no path found the url.
str converter is defined as follows:
class StringConverter:
regex = '[^/]+'
# other methods
Which means it requires at least one character (note +, not *). You can create a new url mapping and manually pass empty string as sort parameter:
path('posts/', views.posts, kwargs={'sort': ''})
You can also register your own converter to allow empty string or just switch to plain old re_path. These options are preferred in case if you want to reduce code repetition and reuse this behavior somewhere else. They also allow you to keep the same url name (useful if you're planning to reverse urls)

How to have exception for some words - Regex in django url pattern?

In my website, people can visit other's profile with url like https://example.com/slug-profile, here is the pattern:
path('<slug:slug>',views.profile,name='profile')
I also want that users go to settings,notifications:
path('settings',views.param,name='param')
# https://example.com/settings
path('notifications',views.notifications,name='notifications')
# https://example.com/notifications
But in this case, settings will be considered as a slug. I have already set a function to avoid users to have slug like settings or notifications.
I see that some websites use a prefix or something similar
www.example.com/user/settings/
www.twitter.com/i/notifications/
In my project I would do:
re_path(r'^(?P<slug>\w{5,})$',views.profile,name='profile')
path('i/settings',views.param,name='param')
i or user will never be considered as a slug profile since the slug regex expression must have at least 5 characters.
How to have thees words or a list of words ['settings','notifications'] as exceptions in a regex pattern?
Or
Do I need to go with example that contains i user in url?
The solution is simpler than this. Just put your specific URLs first; since patterns are always matched in order, settings and notifications will match their own paths and not the slug path.

Remove whitespaces from a url in Urlpatterns (django)

I'm new to Django and I'm developing a project in which there are profile pages.
Well, the problem is that the primary key has whitespaces but I don't want them to show in the url, neither like "%20%", I want to join the words. For example:
website.com/Example Studios --> website.com/examplestudios
I've tried this:
url ( (r'^(?P<studio_name>[\w ]+)/$').replace(" ", ""), views.StudioView, name = 'dev_profile')
But didn't work (it seems like it turns the raw part to string before reading the url) and with 're' happens the same. I've been searching for solutions but I'm not able to find them (and slugify doesn't convinces me).
What's solution to this or what do you recommend?
In urls you define patterens which Django will catch e.g. r'^test/$' this means that when someone try to get yourdomain.com/test Django will catch it and call the view which will probably render template. You need to solve your problem on url generation e.g. in template . Therefore in urls:
url ( (r'^(?P<studio_name>[\w ]+)/$'), views.StudioView, name = 'dev_profile').
You need to transform primary key to word without space in template. One way is to use slug for every record.
Also add slug field to Studio model which is autogenerated and non-editable field(you can generate it from name e.g. Example Studios->examplestudios).

When should I use a URL tag in a Django template?

I finished reading (url in Built-in template tags and filters).
When are URL tags useful?
The URL tag is used when you want to link to a view. You do NOT want to have the view URL hard-coded into your template - so you use the URL tag. That way if you change the URL to your view, you do not need to comb through every single template and make sure that your hard-coded URL to that view is changed as well.
You can also pass variables for the view that you are linking in the template tag as outlined below.
Let's say you have a view called section, like so:
def section(request):
code....
And in the section template, you want to pass a parameter to a different view, people:
def people(request, section_id):
code....
Notice that people takes a parameter, section_id. So in your section template you could use the url tag in a link, passing the section_id, like so:
Link to People View - Passing Section_ID
And in the people template you can link back to the section view - which does not need any parameters:
Link to Section View - No parameters needed
Edit: It looks like starting in Django 1.5, the first parameter, the view, must be in quotes like so:
{% url 'views.section' %}.
Since 1.5 is still in dev, I'm going to leave the above as 1.4 style.

How to have a URL like this in Django?

How can I have URLs like example.com/category/catename-operation/ in Django?
Also in some cases the user enters a space separated category, how can I handle that?
E.g if the user enters the category as "my home", then the URL for this category will become
example.com/my home/ which is not a valid URL.
How can I handle these things?
If you want to keep your URLs pretty, for example when a user enters "my category" you could have "my-category" instead of "my%20category" in the URL. I suggest you look into SlugField (http://docs.djangoproject.com/en/dev/ref/models/fields/#slugfield) and prepopulating that slugfield using ModelAdmin's prepopulated_fields attribute.
http://example.com/my%20home/ is a valid URL where space character is escaped and Django will do all escaping/unescaping for you.
You can use the slugify template tag within your views to deal with spaces and such like so:
from django.template.defaultfilters import slugify
slugify("This is a slug!") # Will return u'this-is-a-slug'
You can try an improved version of SlugField called AutoSlugField which is part of Django Custom Management Command Extensions.
You could consider adding a URL-friendly name to your category and using that in the URL instead.
As another example you could have example.com/tv/ and have the category called "Televisions."
How can I handle these things?
If you want to handle this thing, to obtain my-url, then use the form field clean method to return the valid url. Thats what it is meant for.

Categories