Accessing a named view from a template in django - django

Suppose I have two Apps AppA and AppB
|_AppB
| |_urls.py # url(r'^create/', views.user_profile, name="name_user_profile"),
|
|_AppA
|_urls.py
|_templates
|_file.html
Now in file.html I have something like this
{% block content %}
Success !!!
goto <a href={% url `name_user_profile` % }> Manage Profile </a>
{% endblock %}
However name_user_profile cant be recognised ? Is there anything i have to do to get it recognised ?
Update:
This is what I have done so far
In my main app urls.py (the one with settings.py). I added the following
url(r'^profile/', include("UserProfile.urls" , namespace="UserProfile" , app_name="UserProfile")),
Now in my UserProfile app where the view is located I have this
urlpatterns = [
url(r'^$', views.user_profile, name="name_user_profile"),
]
and the template which which needs to call that view is located in the 3rd app
called accounts which has this
goto <a href={% url 'UserProfile:name_user_profile' % }> Manage Profile </a>
But that does not seem to work

Since your apps reference different urls.py files, in order to use named URLs you will need to access each one with its own namespace.
Check out the example in the docs here. There is a urls.py file that uses include('polls.urls'). Then, in the actual Polls app, there are a couple of named URLs, index and detail. Since they're inside an app those urls can be accessed by using their namespace - {% url 'polls:index' %} and {% urls 'polls:detail' %} respectively.
If you are working before Django 1.9, you have to specifically supply the namespace argument after the include statement. Starting in 1.9 Django automatically uses the app name for the namespace when you include a urls.py file from an app.

Related

django 1.11 html "href" doesn't work with template url

My urls.py
urlpatterns = [
url(r'^index', views.index, name='index'),
my views.py
def index(request):
return render(request, 'index.html', {})
index.html
<ul>
<li>All Contacts</li>
</ul>
My page with the href hyperlink not working
The source:
So I had a look at https://www.w3schools.com/tags/att_a_href.asp and it indicates that relative paths only work if it's pointing to a file. Not sure what I'm missing here?
<ul>
<li>All Contacts</li>
</ul>
use this as href needs to be before the <li> tag
Here:
All Contacts
Your <a> tag is empty. You want to put the link text inside the tag:
All Contacts
Oh and while we're at it:
I had a look at https://www.w3schools.com/tags/att_a_href.asp and it indicates that relative paths only work if it's pointing to a file
The exact text is: "A relative URL - points to a file within a web site (like href="default.htm")". But that's still complete BS, there's no notion of file here, a "relative url" (actually an absolute or relative path) is resolved against the current domain (and the current path if it's a relative path), how the resulting url is served depends on the software serving this resource. FWIW, Django's urls (the one built by the {% url %} tag) are always absolute path.

Build-in views?

I installed a module to Django and this module has ceertain views within itself. Also it comes with a demo to see the features. I am looking at the code from the demo for a while now but I cant figure out how a template is rendered over the build in views.
The module i'm working with is swingtime:
Here is an example:
Excerpt from the template:
<a class="plain" href="{% url 'swingtime-daily-view' prev_day.year prev_day.month prev_day.day %}">
URL Directory
urlpatterns = [
url(r'^$', TemplateView.as_view(template_name='intro.html'), name='demo-home'),
url(r'^karate/', include('karate.urls')),
url(r'^admin/', include(admin.site.urls)),
url(r'^docs/?$', RedirectView.as_view(url='/docs/index.html', permanent=True)),
url(r'^docs/(?P<path>.*)$', serve, dict(document_root=doc_root, show_indexes=False))
]
So the url must somehow link to a built-in template i suppose?
When I try to implement similar code in my project the url can not be reversed?
And also: How would one edit the template for such a build in view?
Thank you!
Check the urls.py file in the karate module. you will find the url there.
It will be something like
urlpatterns = [
...
url(r'daily-view', view='view_name' name='swingtime-daily-view'),
...
]
Now the name argument of the url is the important thing you're looking for as I don't know the actual path or view set there.
So when you have something like this
<a class="plain" href="{% url 'swingtime-daily-view' prev_day.year prev_day.month prev_day.day %}">
The url dispatcher will look through the app urls for the url with this view....this is called named url patterns.
Read more on how url patterns work URL DISPATCHER IN DJANGO

django url NoReverseMatch works in 3rd party app but not my project

I am integrating django-zinnia 0.12.3 into my django 1.4 project. I have it installed and working. I want to override its zinnia/base.html template so that all the content appears using my site's template. The zinnia templates extend 'zinnia/base.html'.
When I copy the file zinnia/templates/zinnia/base.html to myproject/templates/zinnia/base.html all the zinnia {% url %} stopped working and gave NoReverseMatch. Even if I made zero changes to the file. For example:
{% url 'zinnia_entry_archive_index' %} --> returns:
NoReverseMatch Reverse for ''zinnia_entry_archive_index'' ... not found
{% url 'admin:app_list' 'zinnia' %}" title="{% trans "Dashboard" %} --> returns:
NoReverseMatch u"'admin" is not a registered namespace
I was solved the problem by removing the quotes around the url names, for example:
{% url zinnia_entry_archive_index %}
However, if I remove the copy of base.html that I put in myproject/templates/zinnia (in other words it uses the original one in the zinnia project), the urls work again.
My question is why does it work with the quotes inside the original zinnia folder, but not from within my project folder?
The reason is that in Django <= 3 the url tag takes url name without quotes. But in Django 1.4+ it is deprecated and url name without quotes is gone in Django 1.5:
So if you are using Django <= 1.4 do not remove the quotes (unless you are passing context variable) around url names. Instead do this for compatibility reason if you ever wanted to upgrade your django version:
{% load url from future %}
{% url 'zinnia_entry_archive_index' %}
Documentation
Don’t forget to put quotes around the function path or pattern name!
Changed in Django 1.5: The first parameter used not to be quoted, which was inconsistent > with other template tags. Since Django 1.5, it is evaluated according to the usual rules: > it can be a quoted string or a variable that will be looked up in the context.

Django url handling?

After decoupling url file to our app we are facing problem:
Example:
http://www.oursite.com/ourprefix/xyz/wsz
How to handle urls in template ( to accomodate for any prefix(ourprefix) in url)
How to do HttpResponseRedirect without hard-coded urls (also outprefix problem is present here)
Use named urls in urls.py.
Use the {% url name %} template tag. It will insert the correct path.
Use reverse('name', **kwargs) for the redirect.
an example:
in proj/urls.py:
patterns = patterns('',
(r'^prefix/', include('proj.app.urls') ),
)
in proj/app/urls.py:
patterns = patterns('',
url(r'object/^(?P<pk>\d+)/edit/', edit_object_view, name="edit"),
)
in proj/app/views.py:
return HttpResponseRedirect(reverse('app:edit', {'pk':pk}))
in proj/app/templates/app/my_template.py:
<a href="{% url app:edit pk=pk %}"> <!-- generates /prefix/object/123/edit/ -->
If I understand you right, you want to resolve a particular view to a URL inside the template?
You should use the url-reverse method in Django. See here.
1) For the template, you can use:
Link
Where the "prefix" is a variable set in your Context that you pass to the template. You can also dynamically pick the right URL:
{% url application.views.viewfunc parameter1 parameter2 %}
See here for more details.
2) So to HttpResponseRedirect, you can do:
HttpResponseRedirect(reverse(your_view_function))
It also accepts parameters.

How to use namespace urls with django in a reusuable app

I have a django app, a forum app, that has templates with it. In those templates, there are urls that point to parts of the app. For instance the thread_list template has links to each thread like so:
{% for thread in threads %}
{{thread.title}}
{% endfor %}
The thing is, I don't really like calling my urls "forum_thread". I prefer just "thread" and using the namespace feature of django. "forum_thread" may be used somewhere else in the project (namespace collision).So it will look like this:
{% for thread in threads %}
{{thread.title}}
{% endfor %}
but this doesn't feel like the correct way to do this. The docs are kind of unclear here.
I want this app to be reusable and easy to configure. But I also want to use the best standards. I don't want to have the to make the user specify their own namespace name, and then have them edit every single url in each template.
How should I do urls in this app?
From what I can gather you should be able use {% url forum:thread thread %} as you've described. Namespaces always seem to be defined with two variables, namespace and app_name.
If you then do the following in urls.py:
url(r'^/forum/', include('forum.urls', namespace='forum', app_name='forum')),
url(r'^/foo/', include('forum.urls', namespace='foo', app_name='forum')),
url(r'^/bar/', include('forum.urls', namespace='bar', app_name='forum')),
In my understanding, this defines 3 instances of the app 'forum', 'foo', 'bar', and the default (which has namespace==app_name).
When you reverse forum:thread, it uses the current context to determine which one to use- if you are in namespace 'foo' it will use that, otherwise it will fall back on the default.
If anyone is able to clarify how Django decides what the 'current' namespace/app is that would be very helpful. I currently categorise it as 'black magic'.
Some clarification on the actual difference between namespace and app_name would also be helpful- it's possible that I have this totally reversed. The current docs are highly ambiguous.
Note: I have this working for initial requests, but I'm currently unable to make this work for AJAX requests- those always use the default instance for some reason.
This might be a simple syntax error. I was following the Django Tutorial, and I changed mysite/urls.py improperly. The original syntax:
url(r'^polls/', include('polls.urls')),
The desired change:
url(r'^polls/', include('polls.urls', namespace="polls")),
What I did:
url(r'^polls/', include('polls.urls'), namespace="polls"),
Correcting the syntax resolved the issue.
based on my understanding of this question:
in Django 2.1.7
You can app name in app's urls.py file
# app's urls.py
from django.urls import path
from . import views
app_name = 'forum'
urlpatterns = [
path('thread/', views.mark_done, name='thread')
]
in main urls.py
# urls.py
....
urlpatterns = [
path('forum/', include('forum.urls')),
]
then you can employ {% url 'forum:thread' %} in your template
If you wanna use it in a for loop
I think we should
create a view return all threads as context
then add a path to that view
...
path('thread/<int:pk>', views.mark_done, name='thread')
the url in template will like:
{% for thread in threads %}
{{thread.title}}
{% endfor %}