I've been searching for hours to try and figure this out, and it seems like no one has ever put an example online - I've just created a Django 1.2 rss feed view object and attached it to a url. When I visit the url, everything works great, so I know my implementation of the feed class is OK.
The hitch is, I can't figure out how to link to the url in my template. I could just hard code it, but I would much rather use {% url %}
I've tried passing the full path like so:
{% url app_name.lib.feeds.LatestPosts blog_name=name %}
And I get nothing. I've been searching and it seems like everyone else has a solution so obvious it's not worth posting online. Have I just been up too long?
Here is the relevent url pattern:
from app.lib.feeds import LatestPosts
urlpatterns = patterns('app.blog.views',
(r'^rss/(?P<blog_name>[A-Za-z0-9]+)/$', LatestPosts()),
#snip...
)
Thanks for your help.
You can name your url pattern, which requires the use of the url helper function:
from django.conf.urls.defaults import url, patterns
urlpatterns = patterns('app.blog.views',
url(r'^rss/(?P<blog_name>[A-Za-z0-9]+)/$', LatestPosts(), name='latest-posts'),
#snip...
)
Then, you can simply use {% url latest-posts blog_name="myblog" %} in your template.
Related
I'm trying to make a picture the url to the post the picture represents, and I must be doing something wrong, but I don't know what.
I am getting this error when trying to visit the home page of my site.
Error during template rendering
In template .../home.html, error at line 48
Reverse for 'view_post' with keyword arguments '{'post_id': ''}' not found. 1 pattern(s) tried: ['post/(?P[0-9]+)/$']
and the code it showcases
<img src="media/{{ item.image }}">
Also this is my view
def view_post(request, post_id):
post = get_object_or_404(Post,id=post_id)
return render(request,'gram/view_post.html',{'post': post})
And url
url(r'^post/(?P<post_id>[0-9]+)/$', views.view_post, name='view_post'),
Thank you for your help.
I make some assumptions based on your code examples. This line:
post = get_object_or_404(Post,id=post_id)
says that the class Post has a property id. However in your template you call post.post_id. Assuming that post is an object instance of the class Post, it should have the property id. Probably there is no such property like post_id in the class Post.
This means that in the template post.post_id won't return an output. Your urls, which are not shown here, expect an integer ['post/(?P[0-9]+)/$']. Therefore the error is thrown.
Try this snippet:
{% url 'view_post' post_id=post.id %}
and check what happens.
As I said, this is based on some presumptions and I don't guarantee success.
Turned out I'm just stupid and made it hard for myself. The problem was I've done <a href in my home.html and home view didn't know what post.id is - obviously. The problem is fixed.
I know I can get the previous URL in the template by using the following:
{{ request.META.HTTP_REFERER}}
But I want to know if I there's a way to get only the path and not the absolute URL
(i.e /my-page instead of http://localhost:8000/my-page)
Like in the view we can do:
from urllib import parse
parse.urlparse(request.META.get('HTTP_REFERER')).path
Can I do something like that in the template as well?
Update (with more info): My usecase is to compare the previous url with another url within the same site to see if the user came in from there
Looks like there isn't a direct way to do that in the template, so this is what I ended up doing in the template to check if a particular (relative) url is part of the previous (absolute) URL :
{% url 'schoollist:add_school' as add_school_url %}
{% if add_school_url in request.META.HTTP_REFERER %}
Thanks for adding!
{% endif %}
A possible way to achieve this is to use urlparse to get components out of the referer URL, then get the relative path.
If you handle it with custom code this probably won't do much difference for basic cases but probably do some good with fancier edge cases:
from urlparse import urlparse
referer = request.META.get('HTTP_REFERER')
path = urlparse(referer).path
See: Parse URLs into components
I'm a begginer grasping at straws with difficulty dealing with the django slug url system and these NoReverseMatch errors that make no sense to me even after reading the docs.
I have a django project. In one of the views, I pass a list of geoJSON features into a template, and show them on a map. I want to have each feature act as a clickable 'link' to a view that will show stuff about it. The following is part of the template that has those features that I want to click on:
//part of the template:
<script type="text/javascript">
...
function onEachFeature(feature, layer) {
layer.on('click', function (e) {
window.location.href = "{% url 'polls:areadetail' feature.properties.myslug%}";
});
}
(I have confirmed that feature.properties.myslug does in fact contain the slug I want).
The url pattern I want to go to:
urlpatterns = [...
url(r'^areadetail/(?P<areaslug>[-\w]+)/$', views.AreaDetail, name='areadetail'),]
And the view it relates to:
def AreaDetail(request, areaslug):
area = get_object_or_404(Area, nameslug=areaslug)
return render(request, 'polls/areadetail.html', {'area':area})
The issue I get is, by doing what I show and placing that url reference inside that template I show above, that I want to be able click on, that template won't even work at all, giving me a 'Error during template rendering' full page error info that starts with:
NoReverseMatch at /polls/areas/
Reverse for 'areadetail' with arguments '('',)' and keyword arguments '{}' not found. 1 pattern(s) tried: [u'polls/areadetail/(?P[-\w]+)/$']
Any help would be immensely appreciated
EDIT part1: As I've said in response to falsetru, I'm sure feature.properties.myslug has in fact got a slug expression in it.
EDIT2: Based on something I found in a django ticket, I've made a slight change in the url regex at urls.py, from (?P<areaslug>[-\w]+)/$ to (?P<areaslug>[-\w]+)?/$ and now the error is:
Page not found (404)
Request Method: GET Request URL: http://127.0.0.1:8000/polls/areadetail// Raised by: polls.views.AreaDetail
Is it possible that because the "{% url 'polls:areadetail' feature.properties.myslug%}" bit is inside javascript, that feature.properties.myslug is not being inserted there correctly? Like some sort of brackets are needed here?
According to the error message, feature.properties.myslug is empty or has no value.
Make sure the feature.properties.myslug is passed correctly from view.
Comment out {% url .. %} temporarily.
Print {{ feature }}, {{ feature.properties }}, {{ feature.properties.myslug }} to see if which part is missing.
Fix view accordingly.
Uncomment {% url .. %}.
After some more digging around I've found the answer to why doesn't this work in another question at:
How to pass javascript variable to django custom filter
The answer to it by Ludwik Trammer says:
Django templates are build on the server side, while JavaScript is executed on the client side.
That means that template code is always executed before JavaScript (as
it is executed by the server, before the page is sent to the client).
As a consequence it is absolutely impossible to mix JavaScript and
Django code the way you want to.
Which clearly applies here. I was focused on problems with the URL template, regex on the urls.py file etc. when the problem was that no matter what I did, because it's in a javascript section, run client-side, that URL template will always be incomplete no matter what I do, therefore being an impossible solution to what I want.
Let's say I have the following pointless example view:
def foo(request, input):
return HttpResponse()
and in a template I have a form:
<form method="get" action="{% url 'foo' ??? %}">
<input id="myinput" type="text" name="myinput">
...
</form>
Finally, I have the following url in my URLconf:
urlpatterns = [
url(r'^foo/(.+)/', views.foo, name='foo'),
]
What I would like to do, is pass the value entered by the user into the input with the id of #myinput to the foo() view function. To put it another way, you should be able to enter bar in the html input, and when you submit the form it will take you to foo/bar/.
I know that within the foo view I could access the value of the input easily with request.GET['myinput'], but I want it to show up in the url as well.
This seems like it should be a fairly common task, but I have not been able to come up with a solution yet. Any suggestions would be appreciated. My Frankenstein's Monster of a first Django site is almost complete, and this is one of last pieces I am missing.
The source of my misunderstanding
Although I did not make this clear in an attempt to simplify my example and avoid using app-specific code, my use case is a simple search view. The view was actually one of the first views I wrote in the start of my Django journey, and I mistakenly was POSTing my data instead of GETing it. This was making it so that if I was searching for the item foo, it would take me to the detail page for foo, but the url would be mysite/search/ (i.e., the search query is not included in the url though it is included in the request), and I can't return to those search results by visiting the url mysite/search/.
While I was using a GET request in my toy example in this question, I didn't realize that I had been using a POST in my app, and that with some minor tweaking I can get the functionality I want for free very easily. I know that all of this is extremely obvious to veteran and even intermediate web developers, but for someone starting from scratch without web or cs experience, things like HTTP can be a little confusing. At least for me it is. Thanks so much to #Two-Bit Alchemist for explaining this in a way that I can understand.
Applying all this to my toy example
I would get rid of the passed parameter in my view:
def foo(request):
# If I want to do something with the search query, I can access it with
# request.GET['search_query']
return HttpResponse()
change my form in my template to:
<form method="get" action="{% url 'foo' %}">
<input id="myinput" type="text" name="search_query">
...
</form>
and change my url to:
urlpatterns = [
url(r'^foo/search/', views.foo, name='foo'),
]
As #Two-Bit Alchemist said: "The rest will happen like magic". If a user enters bar in the input and submits the form, they will be taken to foo/search/?search_query=bar. This is what I was looking for.
I know there is another question with virtually the same title as mine but the solution in that one didn't work for me. My url is like this:
http://domain.com/videos/dvd/1/
If I use either {{baseurl}} or {{ request.get_full_path }} I get just this part:
http://domain.com/videos/
How can I get the entire url? I need to be able to do this from the template level.
EDIT
P.S. it should disregard any parameters that may be in the url.
You could get it in your view and pass it along into your template context so that it is available to you there.
https://docs.djangoproject.com/en/1.3/ref/request-response/#django.http.HttpRequest.build_absolute_uri
full_url = request.build_absolute_uri(None)
# pass full_url into the template context.