django {% url %} template looping - python

my url.py
app_name="application_name"
urlpatterns=[
url(r"^staff/",include('application_name.staff_url', namespace='staff')),
url(r"^customer/",include('application_name.customer_url', namespace='customer')),
]
staff_url.py
from application_name import views
app_name="staff"
urlpatterns=[
url(r"^customers/",views.customers, name='customers'),
url(r"^orders/$", views.orders, name='orders'),
url(r"^payments/$", views.payments, name='payments'),
]
customer_url.py
from application_name import views
app_name="customer"
urlpatterns=[
url(r"^items/",views.items, name='items'),
url(r"^checkout/$", views.checkout, name='checkout'),
url(r"^make_payment/$", views.make_payment, name='make_payment'),
]
staf url would be staff/orders or staff/payments customer urls would be customer/items or customer/checkout etc
In my view file I have put every link inside a list which would be iterated inside the template and placed it inside a session
This is my view.py
staffLink=[
{'linkfield':"customers", 'name':"Customers",'slug':"staff"},
{'linkfield':"orders", 'name':"Orders",'slug':"staff"},
{'linkfield':"payments", 'name':"payments",'slug':"staff"}]
links=staffLink
request.session['links']= links
request.session['sub']= 'staff'
context_dict = {'links':links}
This is my html template
{% for link in request.session.links %}
{% if request.session.sub =="staff" %}
<a href="{% url 'application_name:staff' link.linkfield as the_url %}" class="nav-link">
{% elif request.session.sub =="customer" %}
<a href="{% url 'application_name:customer' link.linkfield as the_url %}" class="nav-link">
{% endif %}
{% endfor %}
Pl
This are the following result
When I include the if statement i.e. {% if request.session.sub =="staff" %}. The following error is produced
django.template.exceptions.TemplateSyntaxError: Could not parse the remainder: '=="staff"' from '=="staff"'
When I exclude the if statement so making it just <a href="{% url 'application_name:staff' link.linkfield as the_url %}" class="nav-link">
I did this for testing purposes. I get the following error
django.urls.exceptions.NoReverseMatch: Reverse for 'staff' not found. 'staff' is not a valid view function or pattern name.
Please what am I to do to get the if statement working alongside the anchor statement

You should write a space between the == and the "staff" string, so:
{% if request.session.sub == "staff" %}
…
{% endif %}
as for the URL, you not refer to a URL which is an include(…) since that is a collection of URLs. For example:
<a href="{% url 'staff:customers' link.linkfield as the_url %}" class="nav-link">

Related

request.path does not match expected dynamic url

I'm trying to highlight specific buttons in the navigation bar when I'm on a specific page and hyperlink to it when i'm not. The url for this page is a dynamic url however and using the {% url ... as var %} syntax is not making the specific buttons highlighted when they should be.
The issue here is that the button does not even show up at all. I narrowed it down to the request.path not matching with the dynamic url path. Normal urls (without the /str:something) seem to match perfectly.
in navbar.html i've tried to define the comparison_url (before all other code) as follows, but nothing seems to work so far:
{% url 'comparison' as comp_url %}
{% url 'comparison' sub_name as comp_url %}
{% url 'comparison' suburb_name as comp_url %}
{% url 'comparison' sub_name=suburb_name as comp_url %}
{% url 'comparison' vergelijking.suburb as comp_url %}
urls are defined as follows in urls.py:
urlpatterns = [
path("vergelijking/<str:sub_name>", views.ComparisonView.as_view(), name="comparison"),
path("signalen/<str:sub_name>", views.RadarView.as_view(), name="signals"),
path("oorzaken/<str:sub_name>", views.CausationsView.as_view(), name="causation"),
]
in navbar.html, where the actual problem lies:
{% url 'comparison' sub_name as comp_url %}
{% url 'signals' sub_name as sig_url %}
{% url 'causation' sub_name as comp_url %}
{% if request.path == comp_url %}
<li class="nav-item mx-0 mx-lg-1"><a class="nav-link py-3 px-0 px-lg-3 rounded active">Vergelijking</a></li>
{% elif request.path == sig_url or request.path == caus_url %}
<li class="nav-item mx-0 mx-lg-1"><a class="nav-link py-3 px-0 px-lg-3 rounded" href="{% url 'comparison' sub_name=suburb_name%}">Vergelijking</a></li>
{% endif %}
my base.html includes the navbar.html and the comparison.html extends base.html. There is no view for the navbar.html or base.html. My comparisonview looks like this (municipality details are loaded into the context):
class ComparisonView(LoginRequiredMixin, TemplateView):
"""map of municipality and suburbs with tooltip info"""
template_name = 'comparison.html'
def get_context_data(self, **kwargs):
context = super(ComparisonView, self).get_context_data(**kwargs)
context['suburb_name'] = self.kwargs['sub_name']
municipality_name = Suburb.objects.get(name=self.kwargs['sub_name']).municipality.name
context['municipality_name'] = municipality_name
suburb_list = Suburb.objects.filter(municipality__name=municipality_name)
suburbs_signals_dict = {}
for s in suburb_list:
suburbs_signals_dict[s.name] = s.get_signals()
context['suburb_signals'] = dumps(suburbs_signals_dict)
return context
I think the mistake is in the way i define my comp_url but i'm not exactly sure. Does anyone know what I'm doing wrong?
the view was missing a request as a parameter (whenever i was calling on request.path, it was equating the to be matched link with null as request.path did not exist). I solved this by adding the path to the context:
context['path'] = quote(self.request.path)
The quote was in my case necessary since self.request.path can have spaces in a url whereas comp_url has '%20' for spaces. After I could call on path like so:
{% if path == comp_url %}
And the problem was solved

TypeError at /edit : edit() missing 1 required positional argument: 'entry'

I am very new at Django and I am working on a web app project. this particular page is supposed to edit an entry and save the entry. but I keep getting the missing 1 required argument
Views.py
# editPage forms
class editform(forms.Form):
content = forms.CharField(widget=forms.Textarea(), label='')
def edit(request, entry):
if request.method == 'GET':
page = util.get_entry(entry)
return render(request,"encyclopedia/edit.html",{
"form":SearchEntry(),
"edit":editform(initial={'content': page}),
"entry":entry
})
#If this is a POST request
else:
form = editform(request.POST)
if form.is_valid():
content = form.cleaned_data["content"]
util.save_entry(entry,content)
page = util.get_entry(entry)
page = mark.convert(page)
return render(request,"encyclopedia/entry.html",{
"form":SearchEntry(),
"page":page,
"entry": title
})
urls.py
from django.urls import path
from . import views
urlpatterns = [
path("", views.index, name="index"),
path("wiki/<str:entry>", views.entry, name="entry"),
path("search", views.search, name="search"),
path("newEntry", views.newEntry, name="newEntry"),
path("edit", views.edit, name="edit"),
edit HTML
{% extends "encyclopedia/layout.html" %}
{% block title %}
Edit {{name}}
{% endblock %}
{% block body %}
<h1>{{title}}</h1>
<form action= "{% url 'edit' %}" method="POST">
{% csrf_token %}
{{ edit }}
<br>
<input class="save btn btn-info" type="submit" value="save"/>
</form>
<p> Click the "save" button to save your entry to the encyclopedia.</p>
<br>
Return Home
{% endblock %}
entry HTML
{% extends "encyclopedia/layout.html" %}
{% block title %}
Encyclopedia
{% endblock %}
{% block body %}
<h1>{{title}}</h1>
{{entry | safe}}
Edit Content
<br>
<br>
Return Home
{% endblock %}
when I change this particular url:
path("edit/<str:entry>", views.edit, name="edit"),
I get a different issue:
Reverse for 'edit' with no arguments not found. 1 pattern(s) tried: ['edit/(?P[^/]+)$']
The problem is in your urls.py file in this line:
path("edit", views.edit, name="edit"),
because views.edit is expecting that you must provide two-parameter request and entry in your url. And in your case entry is missing. Try to add entry in your urlspatterns path, in this case, I'm expecting your entry is int.
path("edit/<int:entry>", views.edit, name="edit"),
and this entry can be your model pk or anything else you want. After modifying your urlspatterns whenever you call edit view in your html you need to do this:
{% url 'edit' entry=your_entry_value %}
instead of:
{% url 'edit' %}

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 regex NoReverseMatch error

Have this html, that i want to pass 2 arguments to a function when that url is pressed:
htmlpage
{% for n in notifications %}
<li style="..."><b>{{ n.title }}</b> - {{ n.description }}
<a href="{% url 'update-notify-status' n.id n.title %}" >Don't show again</a>
{% endfor %}
urls.py
url(r'^notification_htmlv2/update_status/([0-9]{4})/([0-9]{4})$', 'Notifications.views.updateStatus',
name="update-notify-status"),
views.py
def updateStatus(request,noteId,noteTile):
q=History.objects.filter(notification_id=noteId,title=noteTile).order_by('-id')[0]
When i start the program it gives an error of "NoReverseMatch".
Im following this example:https://docs.djangoproject.com/en/1.8/topics/http/urls/
reverse resolution of url's chapter
I bet neither n.id nor n.title matches ([0-9]{4}).
You should update your url pattern to handle any possible id and title values.
Something like:
r'^notification_htmlv2/update_status/([0-9]+)/([a-zA-Z0-9]+)$'

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

Categories

Resources