Remove whitespaces from a url in Urlpatterns (django) - python

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).

Related

django allauth redirect to another page after email verification

I have this issue: I need to redirect to another page when email verification is confirmed and login for the first time after the email verification. I tried to configure this in setting.py, but didn't work.
My settings.py:
ACCOUNT_LOGIN_ON_EMAIL_CONFIRMATION = True
ACCOUNT_EMAIL_CONFIRMATION_AUTHENTICATED_REDIRECT_URL = os.getenv('schools/form-school')
the url in urls.py is: path('form-school', views.school_list_view, name = 'schools' ),
if you have any clue on how to resolve this please comment your ideas, thanks so much!!
When setting ACCOUNT_EMAIL_CONFIRMATION_AUTHENTICATED_REDIRECT_URL you have to specify the URL or named URL pattern associated to the view you want to display. Sometimes knowing the full URL can be tricky and using the named URL pattern comes in handy as it let's you reference your views without having to care about the absolute path where you defined the url. In your case the URL pattern is the string schools that is set as the value the parameter name.
It should be enough to set that as:
ACCOUNT_LOGIN_ON_EMAIL_CONFIRMATION = True
ACCOUNT_EMAIL_CONFIRMATION_AUTHENTICATED_REDIRECT_URL = "schools"
Note that os.getenv() is used when you need to retrieve the value for an environment variable. This is kinda weird in this situation and I doubt that your project is storing the URL/named URL pattern for a particular view in an environment variable (also environment variables with characters other than numbers, letters and underscore may not be well interpreted).

Why do I need to specify HTML file in render()

Why do I need to give html file name in render() - I have already set url in my project file in urls.py in django
urls.py
url('view-books',views.viewBooks)
views.py
def viewBooks(request):
books=models.Book.objects.all()
res=render(request,'BRMapp/view_book.html',{'books':books})
Why can I not give in render view-books?
i think you have typo
def viewBooks(request):
books=models.Book.objects.all()
context = {"books":book}
return render(request,'BRMapp/view_book.html',context)
your question why you need html file name in render because render is a function it takes 3 arguments 1st is request second is "path of the html file" 3rd is the context
further explaination
Do you have basic idea how django work first of first you are not giving url in render you are giving path to render which template should be render . django follow mvc pattern you read on it but to simplify it urls just have the routing task they are just there to filter routes not to do any thing in url you can give 3 arguments two are compulsary first the path by which it recognize that the time has come to act the second the function name which direct him where to go then its function responsibilty to process the data
Unfortunately, you didn't return anything in your view. So you need to add return to your function:
def viewBooks(request):
books=models.Book.objects.all()
return render(request,'BRMapp/view_book.html', {'books':books})
You might want to take a look at this tutorial.
https://yourwebsite/view-book is not the same as BRMapp/view_book.html, Django needs to know that one corresponds to the other.
The routing in Django works like this:
The user sends a request to Django with a url.
Django looks through your urls in urls.py for a path that matches what was requested.
When it finds a path, like view-books, that path has a view. The view is just a function (viewBooks()), and Django executes it.
The view function is expected to return the content that the user will see. You could, if you wanted, write the whole page by hand as a string in the return line of viewBooks(), but that's inconvenient, so instead you tell Django to make the page for you, starting from a template. To do so, you call render().
What render() does is take the template and replace all parts that need to be replaced for the user that will see it. But to know what the initial content will look like, it needs to read it from somewhere, and that's the HTML file BRMapp/view_book.html.
The HTML file doesn't need to have the same name as the view, you could have called it foobar.html and it would have worked the same. But regardless of its name, you need to tell Django that you want to use a file (render() tells Django that), and you need to tell Django where that file is. You'll have many different files in different places with different names, and it can happen that you have the same name for templates in different directories, so Django will not attempt to guess which one you want: you'll have to put its path inside render() so that Django knows where to start building the page.
If you gave the URL to render() instead of the path to the file, Django would get to point 5 and then back again to 1 to figure out what that URL means, and so on and so forth forever.

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 do I make custom URLs using django?

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-]+)/$

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