django Removing hardcoded URLs in templates - python

I know that in a template file I can include this code which will return a list of links
{% for q in all %}
<ul>
<li><a href={% url 'detail' q.id %}>{{ q.question_text }}</a></li>
</ul>
{% endfor %}
Now django will search for the name 'detail' in the urls.py file of my app directory and it will automatically give the value of q.id to that argument. But what if I have a url that contains more than 1 variable. So here I can only give one argument i.e, q.id. But what if I want to give more than one argument.
Hope I am clear

Well you can see the urls.py as a declaration of how URLs map to view functions (and class-based views). A url can have an arbitrary number of parameters.
If we have for example the following URL:
url(r'^detail/(?P<year>(\d+))/(?P<name>(\w+))/$', views.detail),
We can see this url as some sort of virtual function that would take parameters like:
def some_url(year, name):
# ...
pass
So we can construct this URL with unnamed parameters:
{% url 'detail' 1981 q.name %}
or with named parameters:
{% url 'detail' name=q.name year=1981 %}

Related

How to make Django url template with variable find the correct url

In my urls.py I have:
path('experiments/charts/<str:part_tag>/', ExpViews.bokehChart, name='part_tag')
I'd like to pass a string argument "part_tag" to the function bokehChart.
and I'm trying to give the "path_tag" string variable some values as follows:
{% for part in parts %}
<ul class="list=group">
{% for datapoint in part.datapoints %}
{{datapoint}}
{% endfor %}
</ul>
{% endfor %}
I get the following error on my webpage:
Reverse for 'part_tag' not found. 'part_tag' is not a valid view function or pattern name.
I know similar questions have been asked, but I can't get it to work in my case.

How to pass urlname as a variable to url tag in django

I have a url defined in urls.py of an application
urlpatterns = [
url(r'^group/create', create_group, name='create_group'),
url(r'^account/create', create_account, name='create_account'),
]
context contains
{'buttons': {'create_account': {'btn_text': 'Create Account',
'secondary': 'Add a new accounting ledger',
'url': 'create_account'}}
How should I use url in the template.
{% for button in buttons %}
<li class="collection-item">
<div>
{% with btn_url=button.url %}
<a class="btn" href="{% url btn_url %}">{{ button.btn_text }}</a>
{% endwith %}
<span class="black-text">{{ button.secondary }}</span>
</div>
</li>
{% endfor %}
The above code in the template throws
Reverse for '' with arguments '()' and keyword arguments '{}' not found. 0 pattern(s) tried: []
How should I pass the url name as a variable into the url template tag?
Or if should I some how generate the whole url in my view itself, how should the url be generated?
I personally don't think it's possible. I suggest you using reverse in your views.py to interpret the url first, then pass the interpreted result into template:
from django.core.urlresolvers import reverse
url = reverse('create_account')
# add url to your context
According to django docs, reverse would have the same result as you use url template tag in the template.
In your context, buttons is a dictionary, so looping through {% for button in buttons %} will only loop through the keys of the dictionary, i.e. ['btn_text',]
You might want to loop through the items or values instead:
{% for key, value in buttons.items %}
<a class="btn" href="{% url value.btn_url %}">{{ value.btn_text }}</a>
{% endfor %}
or, if you don't need the keys, you can loop through the values
{% for value in button.values %}
<a class="btn" href="{% url value.btn_url %}">{{ value.btn_text }}</a>
{% endfor %}
Note that dictionaries are not ordered. If you are worried about the order of the items in the dictionary, then use a different data structure like a list or ordered dict.

django url in template correct way to add parameter

in views.py
class LaViewSet(viewsets.ModelViewSet):
serializer_class = IlSerializer
def get_queryset(self):
ilfiltro = self.kwargs['miopar']
return models.Pippo.objects.filter(pippo=ilfiltro)
in url.py
url(r'^pippo/(?P<miopar>.+)', views.LaViewSet.as_view({'get': 'list'}), name="Serializzata"),
this is a working url:
http://127.0.0.1:8000/pippo/1
but if I put in a template:
{% url '1' 'Serializzata' %};
or
{% url 'Serializzata'?1 %};
keep getting this error:
TemplateSyntaxError: Could not parse the remainder: '?1' from
''Serializzata'?1'
From the docs:
url
Returns an absolute path reference (a URL without the domain name)
matching a given view and optional parameters. Any special characters
in the resulting path will be encoded using iri_to_uri().
This is a way to output links without violating the DRY principle by
having to hard-code URLs in your templates:
{% url 'some-url-name' v1 v2 %}
So in your case:
{% url 'Serializzata' 1 %}
Try this:
<a href="{% url 'Serializzata' 1 %}">

Django NoReverseMatch error with valid url config and views

I'm getting a NoReverseMatch error in my template rendering.
Here's the relevant template:
<ul id='comments'>
{% for comment in comments %}
<li class='comment'>
<img class='gravatar' src='{{ comment.User|gravatar:50}}' alt='{{ comment.User.get_full_name }}' \>
<a href='{% url 'dashboard.views.users.profile' comment.User.id %}' class='user'>
{{comment.User.get_full_name}}
</a>
<p class='comment-timestamp'>{{comment.created}}</p>
<p class='comment-content'>{{comment.comment|striptags}}<br>
{% if user == comment.user or user = report.user %}
Delete</p>
{% endif %}
</li>
{% endfor %}
The error is given on the url 'mokr.delete_comment' line
Here's the view:
def delete_comment(request, comment_id):
comment = get_object_or_404(ReportComment, id = comment_id)
report = comment.MgmtReport
comment.delete()
project = report.project
return HttpResponseRedirect(reverse('show_post', args=(project.url_path, report.id)))
and the section of urls.py
(r'^mokr/comment/(\d+)/delete/$', mokr.delete_comment),
url(r'^mokr/show/([^\.]*)/(\d+)/$', mokr.show, name='show_post'),
You're passing two arguments to the template in your call to reverse in the delete_comment view; args=(project.url_path, report.id) but your urls.py lists;
(r'^mokr/comment/(\d+)/delete/$', mokr.delete_comment),
Which can only accept one parameter.
Alter your urls.py to add a name argument to your delete comment url.
(r'^mokr/comment/(\d+)/delete/$', mokr.delete_comment, name="delete_comment"),
Then try using this in your template;
{% url 'delete_comment' comment.id %}
See naming URL patterns and reverse resolution of URLs

Django 1.1 - comments - 'render_comment_form' returns TemplateSyntaxError

I want to simply render a built-in comment form in a template, using Django's builtin commenting module, but this returns a TemplateSyntaxError Exception.
I need help debugging this error, please, because after googling and using the Django API reference, I'm still not getting any farther.
Info:
This is the template '_post.html'[shortened]:
<div id="post_{{ object.id }}">
<h2>
{{ object.title }}
<small>{{ object.pub_date|timesince }} ago</small>
</h2>
{{ object.body }}
{% load comments %}
{% get_comment_count for object as comment_count %}
<p>{{ comment_count }}</p>
<!-- Returns 0, because no comments available -->
{% render_comment_form for object %}
<!-- Returns TemplateSyntaxError -->
This is the Exception output, when rendering:
Caught an exception while rendering: Reverse for 'django.contrib.comments.views.comments.post_comment'
with arguments '()' and keyword arguments '{}' not found.1
{% load comments i18n %}
<form action="{% comment_form_target %}" method="post">
{% if next %}<input type="hidden" name="next" value="{{ next }}" />{% endif %}
{% for field in form %}
{% if field.is_hidden %}
{{ field }}
{% else %}
{% if field.errors %}{{ field.errors }}{% endif %}
<p
{% if field.errors %} class="error"{% endif %}
{% ifequal field.name "honeypot" %} style="display:none;"{% endifequal %}>
{{ field.label_tag }} {{ field }}
/posts/urls.py[shortened]:
queryset = {'queryset': Post.objects.all(),
'extra_context' : {"tags" : get_tags}
}
urlpatterns = patterns('django.views.generic.list_detail',
url('^$', 'object_list', queryset,
name='posts'),
url('^blog/(?P<object_id>\d+)/$', 'object_detail', queryset,
name='post'),
)
/urls.py[shortened]:
urlpatterns = patterns('',
(r'', include('posts.urls')),
(r'^comments/$', include('django.contrib.comments.urls')),
)
I had the same exact problem, render_comment_form template tag was triggering it.
The issue is certainly with your URL config, you had it set the same way i did:
(r'^comments/$', include('django.contrib.comments.urls'))
The correct way is to remove the '$' after 'comments/':
(r'^comments/', include('django.contrib.comments.urls'))
Otherwise django can't properly include all necessary urls under the path comments/...
Hope this helps.
The error message is indicated that it can't find a reverse url for:
django.contrib.comments.views.comments.post_comment
So basically something isn't configured right in your urls. Without being able to see more of how things are setup it's difficult to know exactly what.
Maybe try re-ordering the urls pattern includes in your urls.py, to force the django comments urls to the top?
I had this same problem today. I was referencing a view in urls.py that I hadn't created yet.
From http://docs.djangoproject.com/en/dev/topics/http/urls/#reverse
As part of working out which URL names
map to which patterns, the reverse()
function has to import all of your
URLconf files and examine the name of
each view. This involves importing
each view function. If there are any
errors whilst importing any of your
view functions, it will cause
reverse() to raise an error, even if
that view function is not the one you
are trying to reverse.
Make sure that any views you reference
in your URLconf files exist and can be
imported correctly. Do not include
lines that reference views you haven't
written yet, because those views will
not be importable.
This error is saying that it found the view django.contrib.comments.views.comments.post_comment
but no args () or kwargs{} were passed.
Its not passing a value for object.id into the url.
Take out the url tag and see if the id of the <div id="post_{{object.id}}"> reflects a proper object.id

Categories

Resources