Django logout url with GET values - django

I have url config based on https://docs.djangoproject.com/en/dev/topics/auth/#django.contrib.auth.views.logout
Here it is:
url(r'^logout(?P<next_page>.*)$', 'logout', name='auth_logout_next'),
In template I use such code:
{% trans "Logout" %}
It works nice, yet I have possible GET value in some pages - ?page=2, so request.path drops those values. How should I pass not only the existing page but also GET values if possible.

{% trans "Logout" %}

Related

How to pass variable in django but not as url parameter

I have this in urls.py:
urlpatterns = patterns('',
url(r'^add_to_cart/(?P<app_label>\w+)/(?P<model_name>\w+)/(?P<obj_id>\d+)/$', AddToCart.as_view(), name='add-to-cart'),
)
and i am using this to call AddToCart view in template:
{% for eg in eyeglasses %}
<p>{{eg}} <a href="{% url 'add-to-cart' eg|app_label eg|class_name eg.pk %}" >Buy</a> </p>
{% endfor %}
This ends up in having a url like this
"127.0.0.1/cart/add_to_cart/product/Sunglass/2/"
which i want to avoid. Is there any different way to pass these variables but without passing them as url parameters?
You can try passing them as querystring parameters instead of in url, so you can build url as
http://127.0.0.1/cart/add_to_cart?app_label=product&product=Sunglass&id=2
Build this in template as
{% for eg in eyeglasses %}
<p>{{eg}} <a href="{% url 'add-to-cart' %}?app_label={{eg.app_label}}&product={{eg.class_name}}&id={{eg.pk}} %}" >Buy</a> </p>
{% endfor %}
In view you can get it as
def add_cart_view(request):
....
product_name = request.GET.get('product')
...
Rather than having a list of links, create a form where you use buttons of type submit. For each button give it a value that you can retrieve from the request. When you submit the form set the method to post rather than get.
You may want to take a look part 4 of the Django tutorial.

how can i accomplish the code below without custom vars in a Django template

{% for voter in opt.voterlog_set.all %}
{% if user.id != voter.voter.id %}
<span data-url="{% url vote %}" data-id="{{ opt.id }}" class="button">vote</span>
{% endif %}
{% endfor %}
In the code above I want to show the vote option once only if the current user hasn't already voted. The code above prints out the vote option multiple times (once for each entry in voterlog). Django doesn't let me set a custom variable such as a boolean which I can you use to toggle a hasVoted variable. How can I fix this code using Django templates?
Thanks for your help
Since, as you mention, there's no way to set state in a Django template, there isn't any sane way to do this if you don't have access to the view code. If you do have access to the view code, the easiest solution -- and, all in all, the most correct solution -- is to set a context variable user_has_voted in the view, instead of iterating through the voterlogs in the template.
But, if you don't have access to the view, you'll have to use a hack involving some client-side code, like rendering Javascript to set the necessary state and then adding some further Javascript to check that state and adjust the DOM after the page has loaded.
It seems like your logic is wrong though. You'd need something that sets state if and only if the current user IS found in the loop, like this:
{% for voter in opt.voterlog_set.all %}
{% if user.id == voter.voter.id %}
<script type="text/javascript">
window.user_has_voted = true;
</script>
{% endif %}
{% endfor %}
<script type="text/javascript">
if( !window.user_has_voted ) {
document.write('<span data-url="{% url vote %}" data-id="{{ opt.id }}" class="button">vote</span>');
}
</script>
Note that this is a particularly nasty hack -- it should only ever be used if you only have access to the templates and have no control over the context variables being sent in to the templates.
Probably this is not what you want, but what about creating the list of voters in your view, and add it to template context. Then
{% if user not in voters %}
"user is allowed to vote"
{% endif %}

Django template, if tag based on current URL value

I want to be able to do an if tag based on the current URL value.
for example, if the current page's url is accounts/login/ then don't show a link, without passing a variable from the view.
I am not sure how I can write an {% if %} tag for this, is it possible?
You can also do this for dynamic urls using:
{% url 'show_user_page' user=user as the_url %}
{% if request.get_full_path == the_url %}something{% endif %}
where your urls.py contains something like:
(r'^myapp/user/(?P<user>\d+)/$', 'show_user_page'),
I know this because I just spent ages drafting a stackoverflow question, when I found the answer in the docs.
I'd say even in simple cases this might be the better approach, because it is more loosely coupled.
If you pass the "request" object to your template, then you are able to use this:
{% if request.get_full_path == "/account/login/" %}
For dynamic urls, you can also use the request.resolver_match attribute (docs):
HttpRequest.resolver_match
An instance of ResolverMatch representing the resolved URL. This attribute is only set after URL resolving took place, which means it’s available in all views but not in middleware which are executed before URL resolving takes place (you can use it in process_view() though).
The returned ResolverMatch object has many useful attributes, such as the view_name attribute, which returns the same name you would have passed to the url templatetag to generate the current url.
view_name
The name of the view that matches the URL, including the namespace if there is one.
See the docs for this and other attributes.
Applying this to the example from #nimasmi's answer, you would get:
{% if request.resolver_match.view_name == 'show_user_page' %}something{% endif %}
where your urls.py contains something like:
(r'^myapp/user/(?P<user>\d+)/$', 'show_user_page'),
Note that when you use URL namespaces, view_name will return the namespace qualified url/view name, e.g. app:urlname.
Compared to the answer by #nimasmi, this simplifies the template code a bit, by not needing the separate {% url %} tag to generate the url to compare with. This is especially true when you do not need to compare view parameters, just the view name. If you do need to compare parameters in the url, you can easily use the ResolverMatch.args and kwargs attributes, though.
Maybe like this?
if "order" in request.path
Using "in" allows you to match URLs like:
customers, customer, customer/new, customer/edit, etc
<ul class="nav nav-pills nav-fill">
<li class="nav-item">
<a class="nav-link
<pre>{% if "order" in request.path %} active {% endif %} "</pre>
href="/orders">Order List</a>
</li>
<li class="nav-item">
<a class="nav-link
<pre>{% if "customer" in request.path %} active {% endif %} "</pre>
href="/customers">Customer List</a>
</li>
<li class="nav-item">
<a class="nav-link
<pre>{% if "product" in request.path %} active {% endif %} "</pre>
href="/products">Product List</a>
</li>
</ul>

Encode URL in Django template

I need to encode an URL created by the {% url %} template tag in order to pass it as an argument in an iframe src which generates a Facebook Like button.
What's an appropriate way to do this? The urlencode template filter doesn't seem to work here. My template code looks like this:
{% url blog_urls/blog_detail slug=p.slug year=p.published_on.year month=p.published_on.month day=p.published_on.day %}
The url tag takes another argument which allows you to create a variable with the value of the url:
{% url foo bar=baz as my_url %}
{{ my_url|filters }}}
Additionally, you can always use the filter tag itself to apply filters to more complex tags, eg:
{% filter urlencode %}{% url blog_urls/blog_detail slug=p.slug year=p.published_on.year month=p.published_on.month day=p.published_on.day %}{% endfilter %}
See https://docs.djangoproject.com/en/dev/ref/templates/builtins/#filter

Display unescaped HTML String in Django Admin change list

I am currently facing a serious problem.
I use the standard django admin interface incl. change list to display one of my models.
The model has got a field, which includes a link (e.g. in database: http://localhost:8000/data/somefile.pdf'>link).
What I want now is that this string is rendered unescaped and displayed as link. I already tried the following in "change_list_results.html":
{% for result in results %}
<tr id="{{ result.1|adminfilter }}" class="{% cycle 'row1' 'row2' %}">
{% for item in result %}
{{ item|safe }}
{% endfor %}</tr>
{% endfor %}
I used "|safe" on the actual item that is output. Furthermore i tried "{% autoescape off %}". Same result, the String got escaped.
Do you see any other way to get the String displayed unescaped?
You want to set allow_tags=True on your method. It's a bit hidden, but it is described in the documentation - about a screen or so down from where this link takes you.