How to send url from template to view in django - python

How can I send a URL from a template to a view? I have noticed that a normal string works but a URL doesn't. Here is what I have tried.
path('imageviewer/<str:theimage>', mainviews.imageviewer, name="imageviewer"),
def imageviewer(request, theimage):
response = render(request, "imageviewer.html", {"theimage": theimage})
return response
How I attempt to pass it : (value.image) is a url
<a href="{% url 'imageviewer' theimage=value.image %}" class="effect-lily tm-post-link tm-pt-60">
Error I Get:
Reverse for 'imageviewer' with keyword arguments '{'theimage': 'https://storage.googleapis.com/katakata-cb1db.appspot.com/images/humours/1643758561'}' not found. 1 pattern(s) tried: ['imageviewer/(?P<theimage>[^/]+)\\Z']
Thank you.

You need to escape the image so that it can be used in a URL, use the built-in filter urlencode
{% url 'imageviewer' theimage=value.image|urlencode %}
Your urlpattern also needs to accept slashes and other chars, use the path converter instead of str as it accepts any non-empty string
path('imageviewer/<path:theimage>', mainviews.imageviewer, name="imageviewer"),

Related

Django: Problem with passing parameters from a template {% url %} to a view

I have this urlpath:
path('download/<str:fpath>/<str:fname>', views.download, name='download'),
And this is the view:
def download(request, fpath, fname):
# some code
In template, I have this href tag and I want to pass those strings as arguments to the download view.
click me
But I get this error:
NoReverseMatch at /
Reverse for 'download' with arguments '('lms/static/lms/files/homework/Math 1/3/3', 'hmm.pdf')' not found. 1 pattern(s) tried: ['download/(?P<fpath>[^/]+)/(?P<fname>[^/]+)\\Z']
How can I fix this?
Url arguments of type str cannot contains / characters. You can see this in the error message which has translated your <str:fpath> to a regex:
tried: ['download/(?P<fpath>[^/]+)/(?P<fname>[^/]+)\\Z']
You should use a path converter for your case (see here).
For example:
path('download/<path:fpath>/<str:fname>', ...)

Django next with query parameters

My website has a list of pages that are under /record and available only with query parameters of type and id. Like so:
/record?type=poem&id=175
I am using the django next redirect to go from the login page to the previous page. I initially used href="{% url 'auth:login' %}?next={{ request.path }}" to redirect, but it didn't take the query parameters (i.e type and id). This takes the user to
/login/?next=/record
I then used href="'{% url 'auth:login' %}?next={{ request.path }}'+window.location.search". However, this doesn't work as well. This takes the user to
/login/?next=/record?type=poem&id=175
but it finally redirects to
/record
How do I redirect using next along with query parameters? Is this behavior not possible?
You need to escape special characters in the URL, namely '?', '&' and '='.
While there is django.utils.encoding.escape_uri_path, it doesn't escape the ampersand (&), which is a problem because it will be interpreted as the end of the next parameter and the beginning of another.
Instead, you can use urllib.parse.quote:
from urllib.parse import quote
current_url_escaped = quote(request.get_full_path())
and in the template:
href="{% url 'auth:login' %}?next={{ current_url_escaped }}
You can use HttpRequest.get_full_path() method along with urlencode template filter to get the current url along with the query string.
HttpRequest.get_full_path()
Returns the path, plus an appended query string, if applicable.
href="{% url 'auth:login' %}?next={{request.get_full_path|urlencode}}

Cannot properly generate URL with captured arguments using {% url %} template tag

I'm running into an issue with supplying captured URL parameters through template tags. I have a URL dispatch with a captured parameter that hands off to another URL dispatch with include() that does not have any captured parameters:
nodemanager.urls:
url(r'^(?P<node_id>\d+)/rank/', include('ranking.urls')),
ranking.urls:
url(r'^setup$', views.setup, name='setup'),
I am using {% url 'setup' node_id=node.id %} in my template which creates the error:
TypeError at /stage1/node/5/rank/setup
setup() got an unexpected keyword argument 'node_id'
If I take out the keyword argument and just use: {% url 'setup' %}, the landing page fails to load and I get the (predictable) error:
NoReverseMatch at /stage1/
Reverse for 'setup' with arguments '()' and keyword arguments '{}' not found. 1 pattern(s) >tried: ['stage1/node/(?P\d+)/rank/setup$']
I know that I need to supply the parameter for node_id to properly reverse the URL. However, the named url "setup" in my ranking app doesn't take any parameters, but the URL that includes it (in the nodemanager app) does.
How would I properly pass the node_id keyword argument using a template tag that points to stage1/node/5/rank/setup, i.e. something of the form {% url 'setup' ... %}. Can I do this?
Let me know if I need to post more context code; I tried to include (what I thought) are the relevant parts.
The original error is not due to the URL reversing, but comes when the view is actually called. This is probably because you have not declared it to take a node_id argument. It should be like this:
def setup(request, node_id):
...
Once you've fixed that, the original url tag syntax should work.

URL trouble to pass parameter

This link can not pass parameter to view.py
profile
It gives an error page not found, 127.0.0.1:8000/profile/edit/
There is not parameter there, even {{costumer.slug}} returns a string
Rest of template has no porblem to pass a parameter like this:
{{j.title}}
What can be wrong here?
Your problem is that you are missing a leading slash, so the browser is concatenating the URL with the one you're already on (you're on '/profile', you click 'edit', you go to '/profile/edit').
But you shouldn't be building up URLs like that. You should use the url tag. Assuming your URLconf is this:
url(r'^edit/(?P<slug>\w+)/$', 'profile.views.edit_profile', name='edit_profile')
you would do this in the template:
<a href="{% url 'edit_profile' slug=costumer.slug %}">

Generic Views NoReverseMatch when using {% url %} in Django

I have a problem to do the reverse command 'url' from the template base.html.
URLS.conf my file looks like this:
dic_info_artigo = {
'queryset': Artigo.modificado.all(),
'date_field': 'data_pub',
}
urlpatterns = patterns('django.views.generic.date_based',
(r'^$', 'archive_index', dic_info_artigo,'artigos'),
(r'^(?P<year>\d{4})/$','archive_year', dic_info_artigo,'artigos_ano'),
(r'^(?P<year>\d{4})/(?P<month>\w{3})/$',
'archive_month', dic_info_artigo,'artigos_mes'),
(r'^(?P<year>\d{4})/(?P<month>\w{3})/(?P<day>\d{2})/$',
'archive_day', dic_info_artigo,'artigos_dia'),
(r'^(?P<year>\d{4})/(?P<month>\w{3})/(?P<day>\d{2})/(?P<slug>[-\w]+)/$',
'object_detail', dic_info_artigo,'detalhe_artigo'),
)
base.html
<a href="{% url artigos %}"> Artigos </ a>
The error:
dictionary update sequence element # 0 has length 1; 2 is required
Already tried using the parameter 'name=', i change the value , but it did not work
url(r'^$', 'archive_index', dic_info_artigo, name='artigos'),
What am I doing wrong? Any tips?
Thanks.
The error message suggests that you have tried to name a view using something like:
(r'^my_url$', 'my_view', 'my_view')
However, the third argument should be a dictionary, not the name of a view.
To prevent errors like this, I recommend always using the url shortcut and naming the url pattern:
url(r'^my_url$', 'my_view', name='my_view')
However, you could pass an empty dictionary as the third argument if prefer:
(r'^my_url$', 'my_view', {}, 'my_view')
The urls.py you have posted looks ok, so the problem is probably in a different urls.py. If you're lucky, the full traceback might give you the exact line of the module where the error is occurring.
Use url() to name the urls and try the following in template file.
{% url 'artigos' %}

Categories

Resources