How to pass variable in django but not as url parameter - django

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.

Related

Reverse for 'x' not found. 'x' is not a valid view function or pattern name

I have three pages - homepage, http://127.0.0.1:8000/, displaying one paragraph sentence and two links in the header. and list of pizzas, http://127.0.0.1:8000/pizzas . Now i was trying to add links for each pizza on http://127.0.0.1:8000/pizzas page, so that one could click on them and see what toppings were available. I'm probably stuck because of my decision to use paths instead of url() for mapping urls, which the book i'm following uses.
Error : NoReverseMatch at /pizzas.
Reverse for 'pizza_w_toppings' not found. 'pizza_w_toppings' is not a valid view function or pattern name.
pizzas.html -
{% extends "pizzeria_app/base.html" %}
{% block content %}
<h1> Available Pizzas : </h1>
<ul>
{% for pizza in pizzas %}
<li> <a href = {% url 'pizza_w_toppings' %}> {{pizza}}</a><li>
{% empty %}
<p> We're outta Pizzas. next time bro! <p>
{% endfor %}
</ul>
{% endblock content %}
app/urls.py :
urlpatterns = [
#homepage
path('', views.index),
#show available pizzas
path('pizzas', views.pizzas),
path('pizzas/<int:pizza_id>', views.pizza_w_toppings, name="pizza_w_toppings")
Views:
I'm new to StackOverflow and can't figure out how to add my views.py. i attached a picture, sorry
views.py screenshot
Your url tag should be {% url 'pizza_w_toppings' pizza.id %}. If you check the documentation, you'll see all possible variations of url tag.
For example, suppose you have a view, app_views.client, whose URLconf
takes a client ID (here, client() is a method inside the views file
app_views.py). The URLconf line might look like this:
path('client/<int:id>/', app_views.client, name='app-views-client')
If this app’s URLconf is included into the project’s URLconf under a
path such as this:
path('clients/', include('project_name.app_name.urls'))
…then, in a template, you can create a link to this view like this:
{% url 'app-views-client' client.id %}
The template tag will output the string /clients/client/123/.
If you use namespaces, make sure to include namespace in your url tags like this:
{% url 'your-namespace:app-views-client' client.id %}

Using {% url 'view_name' object %} directly

The approach of doing {% url 'view_name' object.pk object.parent.slug %} isn't really flexible when switching to completety different url patterns. I'm looking for a way to do {% url 'view_name' object %} and to transcribe myself from object to object.pk and object.parent.slug in the url.
Like that
- template.html
{% url 'view_name' object %}
- urls.py [not real regex regex]
url('<object__parent__slug>/<object__pk>', views.view_name, name="view_name")
I know this is not at all possible with this syntax, but it's just to give an idea of what I'm looking for.
I will just add url methods inside my models:
class House(model.Models):
name = models.TextField()
....
def get_edit_url(self):
return reverse('view_name', {'pk':self.pk, 'name':self.name, 'owner_pk' : self.owner.pk })

URL template optional param

Let's consider this template part
<form class="form-horizontal" action="{% if client_id %}
{% url client_edit client_id=client_id %}{% else %}
{% url client_edit %}
{% endif %}" method="post">{% csrf_token %}
{{ client_form }}
</form>
As you can see the parameter client_id is optional.
Is there a way to avoid this repetition (url client_edit) ?
Url pattern:
url('^client/edit$', client_edit, name='client_edit'),
url('^client/edit/(?P<client_id>\d+)$', client_edit, name='client_edit'),
It's not repetition of using
{% url client_edit %}
since you actualy define two urls. If you really want to make it shorter (not necessary simplier) you could create some filter like
{{client_id|make_url}}
and inside filter you can resolve to proper url
urls don't have optional parameters. You can have multiple patterns point to the same view (as you have done), and then check for the defaults in the view. In your template, {% url client_edit client_id=client_id|default_if_none:-1 %}, then depending on what you want to happen on the view end filter appropriately:
def client_edit(request, client_id = None):
if client_id:
client = get_object_or_404(Client, pk=client_id)
else:
# Default value for client
client = Client.objects.filter(active=True) # for example
# your normal logic here

Django logout url with GET values

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" %}

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