Error during template rendering - django

i am trying to render the details page of the product by giving the url www.example.com/product_name/product_id. But i am getting this error.
Reverse for 'product_details' with arguments '(u'lehnga choli', 43)' and keyword arguments '{}' not found. 1 pattern(s) tried: ['(?P[a-zA-Z]*)/(?P[0-9]+)/$']
here is my urls.py
url(r'^(?P<product_name>[a-zA-Z]*)/(?P<product_id>[0-9]+)/$', 'designer.views.product_details', name='product_details'),
and here is my urls in html template
{% url 'product_details' designs.name designs.id %}
and this is my views.py
def product_details(request, product_name, product_id):
design = Design.objects.get(id=product_id)
return render_to_response("designer/product_detail.html", {
"design":design,
"current": "product_detail",
}, context_instance=RequestContext(request))

There's a space in the name (which can't be used in a URL). As I mentioned in my comment, you might want to look into a SlugField
However, since you're looking up the Design by id in your view, it doesn't really matter whether the model has a slug. You can use the template tag slugify to just make it passable through the URL.
{% url 'product_details' designs.name|slugify designs.id %}
This does require a small tweak to your URL as well, because spaces are replaced with a - - and I just use \w in general.
url(r'^(?P<product_name>[\w-]+)/(?P<product_id>[0-9]+)/$', 'designer.views.product_details', name='product_details'),

Related

i am not able to render my urls in my template it gives me error rendering

NoReverseMatch at /
Reverse for 'Jersey' with no arguments not found. 1 pattern(s) tried: ['Jersey/(?P[^/]+)/$']
Below is the code to my views.py
class JerseyView(TemplateView):
#paginate_by=3
template_name='Ecommerce/Jersey.html'
def get_context_data(self, **kwargs):
et =super(JerseyView, self).get_context_data(**kwargs)
et['United']= Item.objects.filter(category="3").filter(subcategory="9")
et['Chelsea']= Item.objects.filter(category="3").filter(subcategory="10")
return et
below is the code for my urls.py
path('Jersey/<slug>/', JerseyView.as_view(), name="Jersey" ),
I called This link in my Navbar as
<a class="dropdown-item" href="{% url 'Ecommerce:Jersey' %}">Men's Clothing</a>
when I click on it it gives me the error as NoReverseMatch at / Reverse for 'Jersey' with no arguments not found. 1 pattern(s) tried: ['Jersey/(?P[^/]+)/$']
I don't know if there's something i am missing out because i have checked my spelling and still getting the same error
By using {% url 'Ecommerce:Jersey' %}, you're trying to access Jersey/<slug> path without giving any argument. So Django router expect a argument on this path (slug).
You need to provide it, (only you knows what slug goes there...) like this :
{% url 'Ecommerce:Jersey' Jersey.slug %}
is this slug dynamically change or not? if it is then first you should correct your url like this: 'Jersey/<slug:slug>/' and in href tag, get slug from context you passed in views.py like what user BriseBalloches said. but if your slug is a fixed parameter, you can just write it in href tag. suppose your slug parameter is country then your href tag should work with href="Jersey/country" or href="{% url 'Ecommerce:Jersey'country %}"
these href tags will generate http://127.0.0.1:8000/Jersey/country

What is the optimal way to write function-based views in Django?

What is the recommended way to write views (as functions) in Django?
I am asking in terms of readability, etc.
For example: define the template first, then do the translations, then define models and lastly define context.
Here is some example code:
def index(request): # Landing page, translated to the browser's language (default is english)
template = loader.get_template("koncerti/index.html")
# Translators: This is the text on the homepage buttons
concerts = gettext("Koncerti")
band = gettext("Band")
# Translators: This is the option in the language-switch box
foreignLanguage = gettext("eng")
koncertiUrl = '/koncerti/international' # The URL slug leading to 'koncerti' page
bandUrl = '/band/international' # The URL slug leading to 'band' page
translationMode = '' # The URL slug that is leading to slovenian translation mode
context = {
'Concerts' : concerts,
'Band' : band,
'foreignLanguage' : foreignLanguage,
'koncertiUrl' : koncertiUrl,
'bandUrl' : bandUrl,
'translationMode' : translationMode
}
return HttpResponse(template.render(context, request))
I think you are doing too much in the view. A view is supposed to make the proper querysets, and make changes to the database. It's main task is thus to decide what to render, and what to update. Not how to update it.
Deciding about translations, url resolution, etc. is normally a task of the template. The template has template tags for that such as {% trans … %} [Django-doc] and {% url … %} [Django-doc].
Using the {% url … %} over raw URLs you construct yourself is strongly advisable. It makes the odds of making a mistake smaller, and furthermore it is clear to what view you are referring.
You furthermore might want to use render(..) [Django-doc]. This function combines looking for a template, rendering that template with the template render engine, and returning a HTTP response.
from django.shortcuts import render
def index(request):
return render(request, 'koncerti/index.html', {})
In the template, you can then render this with:
{% load i18n %}
{% trans 'Koncerti' %}

How to reach url from form in django

I am new to Django and I have a simple question. Here is a view :
def watchmovie(request, idmovie):
[...]
return render(request, 'movies/watch_movie.html', locals())`
and I would like to create a simple form :
an IntegerField that would redirect to the correct url :
if I submit "42" it will redirect me to the view watchmovie with the parameter 42 as idmovie.
How can I do that?
I tried something like that
<form action="{% url "movies.views.watchmovie" %}" method="post">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Submit" />
</form>
my url.py is
from django.conf.urls import patterns, url
urlpatterns = patterns(
'movies.views',
url(r'^movie/(?P<idmovie>\d+)$', 'watchmovie'),
)
and Django says
Reverse for 'movies.views.watchmovie' with arguments '()' and keyword arguments '{}' not found. 1 pattern(s) tried: ['movies/movie/(?P<idmovie>\\d+)$']
Thank you!
The reason you are getting that error is because of a mistake in your url tag usage. Your watchmovie view url definition expects an argument to be supplied for idmovie. Since you are not supplying any argument in your url tag call, it looks only for urls which do not require an argument. Since there is none, you get an error.
But that is just a symptom. The real issue is that the way you have this structured there is no view listening for a post from your form.
The easier way to structure this is to use the same view to both display the form and to play the movie. If your view is hit with a GET request, display the form. If it is hit with a POST, validate the form (which will contain the movie id) and then respond with the page that plays the movie. That way there is no need to pass idmovie within your url.. you can remove that from your url definition and also remove the need to specify the action= attribute in your tag.. it will just post right back to where it came from.

Django alter current URL name and arguments

In my Django URLs, I have many URL patterns that end with :
(redirect/(?P<redirect_to>\w+))
Which means that these URLs can be (or not) ending by /redirect/TARGET/. These URL patterns have other named arguments (mostly one : pk)
Now, I'd like, in the templates used by these URL patterns, to be able to alter the current page path, by just adding the redirect_to argument, and keeping the other arguments and URL reverse name untouched.
I was able to get the URL reverse name in the template, by adding resolve(path).url_name to the current context, and then to use that with the {% url %} template tag.
I'd like to know if there is any easy way to dynamically add the arguments (from resolve(path).kwargs) to the URL reverse tag ?
I think you should create a custom tag for this (replacing your {% url %} tag with {% url_redirect "your_new_destination" %}).
in your_app/templatetags/my_custom_tags.py:
from django.core.urlresolvers import reverse, resolve
#register.simple_tag(takes_context=True)
def url_redirect(context, new_destination):
match = resolve(context.request.path)
match.kwargs['redirect_to'] = new_destination
return reverse(match.url_name, args=match.args, kwargs=match.kwargs)
in your template:
{% load my_custom_tags %}
{% url_redirect "your_new_destination" %}
Please note that you need to add 'django.core.context_processors.request' to your TEMPLATE_CONTEXT_PROCESSORS in order for this snippet to work.

django {% url %} tag without parameters

I have a url defined as follows:
url(r'^details/(?P<id>\d+)$', DetailView.as_view(), name='detail_view'),
In my templates, I want to be able to get the following url: /details/ from the defined url.
I tried {% url detail_view %}, but I get an error since I am not specifying the id parameter.
I need the url without the ID because I will be appending it using JS.
How can I accomplish this?
Just add this line to your urls.py:
url(r'^details/$', DetailView.as_view(), name='detail_view'),
or:
url(r'^details/(?P<id>\d*)$', DetailView.as_view(), name='detail_view'),
(This is a cleaner solution - thanks to Thomas Orozco)
You'll need to specify that id is optional in your view function:
def view(request, id=None):