Django Clean URLS and Form Data - python

I must have some sort of misconception of how GET variables can be manipulated in django, but here goes:
(1) I have a search form that has two required parameters, and one optional parameters.
The form sends to /search/ like so :
<form action="/search/" method="GET">
However, the urls that result from this look something like
http://mylifeforregex:8000/search/?keyword=keyword&columns=name&exact=on
I'm not able to match it in my urlpatterns with the following line :
url(r'^search/(?P<keyword>\w+)(?P<columns>\w+)(?P<exact>\w+)?$', 'home', name='searched')
So if someone could tell me what exactly I'm doing wrong with this regex, it'd be much appreciated.
(2) The more interesting question I have personally is : is there any way I can change the way the form data will be presented? Is it possible to have the form query result in a url that looks like
http://halp:8000/search/keywordquery/columnquery/optionmarked

In this case, none of the querystring parameters that are appended to the URL will match your pattern, because the pattern is simply not the same.
You would need to pick those up in your 'home' view as such:
[variable] = request.GET.get([key])
To get the url pattern you're expecting, you'd have to do a POST to your view that handles the form to get the values, and then redirect to '/search/[keyword]/[column]/[exact]/'

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)

Python Django: urls.py questions

Need a little help with my urls.py and other stuff.
How can I replicate this in Django?
1) When user requests a non-existent page it will redirect to one up the directory level. Ex: example.com/somegoodpage/somebadpage should be redirected to example.com/somegoodpage.
2) When user requests page example.com/foo/bar/?name=John it will make url to example.com/foo/bar/name=John
3) When user requests page example.com/foo/bar/John it will change url to example.com/foo/bar/name=John.
Any help is greatly appreciated. Thank You.
For 1), if you don't want to do a separate route for every single route on your website, you'll need middleware that implements process_exception and outputs an HttpResponseRedirect.
For 2 and 3, those are rules that are presumably limited to specific routes, so you can do them without middleware.
2 might be doable in urls.py with a RedirectView, but since the relevant bit is a query string argument, I would probably make that an actual view function that looks at the query string. Putting a ? character in a url regex seems strange because it will interfere with any other use of query strings on that endpoint, among other reasons.
For 3, that's a straightforward RedirectView and you can do it entirely in urls.py.
according to django doc for number 1:
django URL dispatcher runs through each URL pattern, in order, and stops at the first one that matches the requested URL, so add a pattern that matches "somebadpage"s and assign it to a view which redirects the user to "somegoodpage".
for number 2:
the doc says "The URLconf searches against the requested URL, as a normal Python string. This does not include GET or POST parameters, or the domain name."
so i don't think that you can get the "?name=John" in url dispather, so if you describe what you want to do maybe I can help better
and for 3:
to capture bits of the URL and pass them as positional arguments to a view you should use named regular-expression groups, for example :
url(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$', 'news.views.month_archive'),
and the request to /articles/2005/03/ would call the function news.views.month_archive(request, year='2005', month='03'), instead of news.views.month_archive(request, '2005', '03').
hope this helped :)

Django template reverse url resolution without creating group for variable

I want to create urls like this;
.../film/slug-of-the-film/id-of-film
.../film/id-of-film
example;
../film/fight-club/1040
../film/1040
two links are same.
when I do like this;
url(r'^(?P<slug>[-\w]+/)?(?P<id>[0-9]+)/$', views.summary, name="film_summary")
I can reverse url from template with {% url film_summary film.slug film.id %}
I dont use slug. It is just for readability. So I try something like that;
url(r'^(?:[-\w]+/)?(?P<id>[0-9]+)/$', views.summary, name="film_summary")
but I can't reverse this from template. Is there any way to do that?
Except solutions like this; /film/{{film.slug}}/{{film.id}}
Actually I don't know is it necessary to do like that. I just aimed to don't add a parameter to view function that I won't use.
Thank you in advance :)
I would handle them as separate urls. That also simplifies the regexp for human readers.
url(r'^(?P<id>[0-9]+)/$', views.summary, name="film_summary"),
url(r'^(?P<slug>[-\w]+/)?(?P<id>[0-9]+)/$', views.summary)

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 can I match the url in html

<form action='/[0-9]+' method="POST">
<input type="submit" value="delete question" name="delete">
</form>
what above is the html template I am using for the appengine project. Besides that, i created a web request handler class to handle this request. ('/[0-9]+',QuestionViewer), it is supposed to catch any url in digits. However, turns on that after I click on the delete button above, my page is directed to some url like main/[0-9], I dont know if I can use regex in the django template, or is there a away that my QuestionViewers class can catch the url in digits? since my url associated with the html page is dynamic, like the parts after / ,like /13,are changing accordingly and I cant do that only works for page 13 but not for /14 or something like these. Hope I make it clear. any helps? Thank you a lot.
That doesn't really make sense. You want to submit your form to a regex rule? What would it match against?
No, the form needs to submit to a specific url. Right now, it's trying to submit to /[0-9]+
If I understand what you are saying, and you want to submit from a url such as /13/ to your QuestionViewer at /[0-9]+, simply submit without the action attribute or set it to "" to post to the current url.
Note that if you want to use the digit captured in your regex, you need to surround your regex in parenthesis such as '/([0-9]+)/$', QuestionViewer or use a named regexp /(?P<id>[0-9]+)/$ to pass in an argument of id equal to the matched regex to QuestionViewer.
http://docs.djangoproject.com/en/1.0/topics/http/urls/#how-django-processes-a-request
The value of the action attribute must be a valid URL.
I think what you want is to generate an actual number for the action url; a number that is the number of the question that you want to delete. For example:
<form action="/1234" method="POST">
You will need to change your code to make sure you do this.

Categories