Django advanced nesting urls - django

Welcome,
I've got a problem where I`m trying to make a deep nesting.
The thing is that I have Menu that has SUBMENU that can have multiple categories and those categories can have multiple services available and those services can have multiple products.
Writing urls for that specific thing was easy but when I'm trying to create a product that has no category and I want it to be displayed directly in SUBMENU the problem is with writing url for that specific product that doesnt overlap with SUBMENU slug.
For example:
MENU > SUBMENU1 > CATEGORY 1 > AVAILABLE SERVICES > PRODUCT 1
MENU > SUBMENU2
MENU > SUBMENU3 > PRODUCT 2
all of those names are slugged and my urls.py looks like this:
url(r'^uslugi/(?P<category_slug>\S+)/(?P<services_slug>\S+)/(?P<service>\S+)/$', views.show_service_details, name='show_service_details'),
url(r'^uslugi/(?P<category_slug>\S+)/(?P<services_slug>\S+)/$', views.show_services, name='show_services'),
url(r'^uslugi/(?P<category_slug>\S+)/$', views.show_categories, name='show_categories'),
url(r'^uslugi/(?P<product_slug>\S+)/$', views.show_product_without_cat, name='show_product_without_cat'),
The thing is that when I try to enter a product with no category (just placed in submenu), my urls are calling the show_category view. Changing sequence of those urls won't resolve my problem, because I won't be able to enter my show_categories because django will try to execute show_product_without_cat
I there a reasonable solution for this without redesigning all structure ?
Unfortunetely even saying to django in template to call specific VIEW doesn't help at all. It just goes through all urls and matches the first one
<a href="{% url 'show_product_without_cat' i.url %}" >
<img src="/media/{{ i.image }}"> <br/>
</a>

URL dispatcher finds the first url that matches the request path and calls the found view. You have the same url regex for both show_categories and show_product_without_cat views so only the first occurrence of url will work.
The only solution is to create an intermediate view which will check the slug against Category or Product model and call the appropriate view.
def product_or_category(request, slug):
if Product.objects.filter(slug=slug).exists():
return show_product_without_cat(request, slug)
return show_categories(request, slug)
And assign the url to this view:
url(r'^uslugi/(?P<slug>\S+)/$', views.product_or_category,
name='show_product_or_category'),
But note that with this solution you can't have a category and product with the same slug.

Related

How to link tags to search results in a Django Blog?

I am building a blog in django and am using django-taggit. I'm trying to figure out how to tie the link of a tag to a search result page that shows all of the posts using that tag.
I already have the search page created, I know how to filter queries to the page to bring the correct results, and know how to link to the page itself {% url 'search' %}. But how would I pass queries to the page from the template?
For instance, if I have a post tagged "dog" I want users to be able to click on the tag "dog" and be taken to the search page that only has results for posts also tagged "dog".
The django documentation for class views does not have examples of this. And every tutorial resource so far has been focused on the filtering and displaying of the search page itself rather than linking to it with desired queries in an <a> tag instead of a <form>.
In short, how do you make an <a> link pass a query into a url, like how an <input> would to a <form> action in Django?
I found the answer. Based on this , it is
<a href="{% url 'myview' %}?q=foobar">

Django redirect to form page and submit the form?

Right now. I have a search function in my page to search for item id. When I click search, I will render the same page with the result items and show item. And in other pages where I also display the item id, I want to add a link to the id to go to the same page where I search for that id.
Example: id: 123, I want the same page when:
1. search '123' in my search page(my search only accept exact match)
2. In other pages, click '123', go to the search page with results
How should I achieve this, I have tried many ways which don't wok.
You need to make use of the GET method that HTML forms provide. When you perform a search from the first page, you must make sure that you are doing so using the GET method in the form. This will append the form data into the URL.
E.g. If you have a 'name' field in your form which has 'John' inputted. The submission of this form will compose a URL like so:
http://someurl.com/?name=John
This can then be accessed using the Django request object:
name = request.GET['name']
You've probably done something similar already for displaying your search results. So, all you need to do is create a link in your second page that redirects to the search page with GET request variables appended.
E.g.
<a href="{% url 'search_page' %}?searchterm=232> Item 232 </a>

Can any one help me to learn reverse url in django

I have a menu in my project and I want to call different Views.
For example, if I have a menu like:
home | about Us | Contact-Us
If I click on home it will call home view successful and then when I click again on home it takes to home/home or when I click on about-us it will take me to home/about-us
Every call (click) on menu will increase home/about-us/home........ like this.
How can I correct 'Url' patterns? I read the documentation but I did not get any idea or solution.
Assuming you have a URL defined for the About page that looks like this:
url(r'^about/$', 'website.views.about', name='about'),
You can reverse a URL in a template like this
{% url 'about' %}
Or you can reverse a URL in your views.py like this
return redirect(reverse('about'))

Unexpected URL concatenation

I have a url for product categories
url(r'^(?P<cat>[^/]+/$)', 'reviews.views.category'),
for example, if I am in the url: http://127.0.0.1:8000/ and click on "eletronics" in the menu, I go to http://127.0.0.1:8000/eletronics/
If I click again in other category (e.g. "books"), I go to http://127.0.0.1:8000/eletronics/books/
How I set up my url in way that I just get one (the last clicked) category in the url?
The menu links in your template may be pointing to "electronics/" and "books/" vs "/electronics" and "/books." To conform with DRY, I recommend naming your url patterns and using the {% url %} template tag to load the correct url route.
For example:
url(r'^(?P<cat>[^/]+/$)', 'reviews.views.category', name='category'),
And in your template:
{% url 'category' 'books' %}
Which will return the correct '/books' url route.

django url parse formatted url

I'm in the design stages of a single page web app, and would like to make it so that a user can click on a formatted URL and the data requests will load in the page.
For example, a url of http://www.mysite.com/?category=some_cat will trigger the Category view with the relevant data.
My intention is to parse the URL, gather the data, then pass it to the index.html template for rendering on page load. Once the page has been loaded, a Javascript trigger setting will trigger the appropriate button to load the client view.
However, I'm having an issue setting up the URL parser, as the following settings are not matching the example url above.
from app.views import app_views, photo_views, user_views, admin_views
urlpatterns = patterns("",
url(r'^/(?P<category>\d+)/$', app_views.index)
)
You're confusing between sending information through your urls with GET and formatting you urls with arguments for the view functions. Say I am visiting a site called http://www.mysite.com/ and the page has a form that looks like this:
<form>
<input type='text' name='category' id='category'></input>
<button type='submit'>Send!</button>
</form>
upon clicking, the url will automatically change to http://www.mysite.com/?category=<value of input>. The ? marks that everything afterwards should be treated as GET data, with the syntax of <id>=<value>. You can then access them like so:
def response(request):
category = request.GET['category']
formatting urls is different, because it means looking for patterns that are part of the url. i.e. a pattern that looks like r'^/(?P<category>\d+)/$' will look for this: http://www.mysite.com/<category>/ and it will send it to the request in your views as an additional argument like so:
def response(request, category):
...
The regex is used to define how you recognize that part of the url. For example, the \d+ you're using means that category needs to be a number. You can search how to define different types of patterns according to your needs
Note that with GET you are sending the data to the same view function that rendered the page you are currently visiting, while using a different url means you tell it where to go through your urls.py (usually a different function). Does that make things a bit clearer?