Function with arguments in a template. Django - django

In my template, I display a list of users a user follows. I would like the user to be able to delete one of the users he follows thanks to a button.
I have a function remove_relationship that deletes a relationship.
Here is the function in my models.py:
class UserProfile(models.Model):
(...)
def remove_relationship(self, person):
Relationship.objects.filter(
from_person=self,
to_person=person).delete()
return
I would like to pass this function into my template:
{% for user in following % }
<form method="post">
{% csrf_token %}
<input type="submit" value="delete" onclick="remove_relationship"/>
</form>
{%endfor%}
The thing is that I can't pass argument in my template. So how can I do so that each button deletes the relationship with the right user?
I saw an other question on this topic, abut it looks like it doesn't solve my problem (http://stackoverflow.com/questions/1333189/django-template-system-calling-a-function-inside-a-model)
Thank you for your help.

It looks as though you are confusing client-side code (JavaScript) with server-side (Django).
To get the relevant user ID submitted you could add an additional hidden field to the form:
{% for user in following % }
<form method="post" action="{% url views.remove_relationship %}">
{% csrf_token %}
<input type="hidden" name="user_id" value="{{ user.id }}">
<input type="submit" value="delete" />
</form>
{%endfor%}
Then create a remove_relationship view that does the deletion on the server side, based on the user id you'll now find in request.POST['user_id']

Related

Passing HTML tag data- to Django with form submit

I am trying to pass data in HTML tag with a form submit to Django
I currently have a template like this:
{% for item in items %}
<div class="product">
{{ item.item_name }}
<form method="POST">
{% csrf_token %}
<input
type="submit"
value="add to cart"
data-pk="{{item.pk}}"
class="add_product"/>
<form>
</div>
{% endfor %}
I want to pass data-pk with a Django form. How do I do that?
Also I know, I can create a view to handle endpoint to do that, and include pk in the url, is that a better solution?
I am new to Django, and I will be grateful for any input on how to do stuff the right way
Instead of data, use value={{item.pk}} and handle the submit logic in your view.

Django filter for result from checkbox form

I'm begginer of django and i try to implement search engine to look for recipes that contains selected ingredients.
I want to do form with all ingredients_type from my Model and user can select up to 3 of them (checkbox prefered). Then i want to filter recepe that contains them.
I was looking for generic form but never get right result.
Right now i have only a scratch and Im looking for any advice
model.py
class IngredientsType(models.Model):
type = models.CharField(max_length=60, blank=True)
def __str__(self):
return self.type
search.html
{% for ingredients in ingredients_type %}
<input type="checkbox" id="{{ingredients.type}}">
<label for="{{ingredients.type}}">{{ingredients.type}}</label>
{% endfor %}
<form method="POST" action="#">
<button type="submit" name="save" value="save">szukaj</button>
</form>
Do i have to create custom form or there is good way to use some of generic form?
I think what you are on the right path, but there are some mistakes in your code.
search.html
<form method="POST" action="">
{% csrf_token %}
{% for ingredients in ingredients_type %}
<input type="checkbox" id="{{ingredients.type}}" value="1">
<label for="{{ingredients.type}}">{{ingredients.type}}</label>
{% endfor %}
<button type="submit" name="save" value="save">szukaj</button>
</form>
model.py
You might want to use many-to-many relationship to represent to relation between the ingredient types and the recipes.
views.py
Make sure you have the POST handling method to work with your filter query. This should get data from the form.

Django Forms to values of html <input> field

I am trying to access the values of a Bootstrap btn-group from Django and from the documentation I have found, it seems that you should use Forms in Django for such tasks.
This is what the html looks like, right now:
<div class="col-md-6">
{% for metric in metrics %}
<input name="{{ metric.name }}" type="hidden" value="0"/>
{% endfor %}
<div class="btn-group" data-toggle="buttons">
{% for metric in metrics %}
<button type="button" class="btn btn-default" data-checkbox-name="{{ metric.name }}">{{ metric.name }}</button>
{% endfor %}
</div>
</div>
How can I use forms to get the values of the input fields?
Here it is a basic example about using a form in django
views.py:
#login_required
def your_view(request): # Add this code into your view
if request.method == 'POST':
# So here you can do a loop over POST fields like this
data_list = [] # We will insert all the inputs in this array
for key in request.POST:
data_list.append(request.POST[key])
# Here you can manage the the data_list and do whatever you need
# The content of the data_list depend on your inputs
# It could be string, integer....
# YOUR VIEW CODE
template (form example):
<form action="." method="post" id="add_user_form">
{% csrf_token %}
{% for metric in metrics %}
<input type="text" name="{{ metric.name }}" placeholder="whatever you want">
{% endfor %}
<input type="submit" value="submit" class="default"/> # Submit button
</form>
{% csrf_token %} : You need to put this in every form you use
action="." : This make the post to the actual page
But anyway I strongly recommend you to check this Django Forms Documentation to unterstand better the logic, and also check the ModelForms because can save you a lot of time when you need to make a form for a model that exists in your Django Models
You are'n forced to use django forms, this is just a way to get a sort of organization.
in you views toy can get the values sent to the server by using request.GET or request.POST, depending of the method of the form.
to get a list of values you have received just do a
print request.POST
request.POST is a dictionary, so you can get any value fron them by its key:
print request.POST['<key>']

Django URL is being changed by a submit button

I'm very new to Django and not super familiar with web programming in general, so it's very likely that there is an easy fix to my problem that I'm just unaware of.
My web app is a photo gallery. People can click on a photo to see an enlarged version with buttons on either side for older or newer pictures. In addition, the photos in the gallery can be sorted by tags, which are passed along as URL parameters.
My problem is that when I click on one of the submit buttons, Django replaces the parameters in my URL with the name of the button, thus destroying my reference to what tag I was using. For example, "127.0.0.1:8000/gallery/view/6/?tag=people" upon clicking next, gets converted to "127.0.0.1:8000/gallery/view/6/?older=Older" when it's trying to process the URL.
Code from my HTML:
<form action="/gallery/view/{{ photo.id }}/?tag={{ tag }}" method="get">
{% if has_newer %}
<input type="submit" name="newer" value="Newer">
{% endif %}
<img src="{{ photo.photofile.url }}">
{% if has_older %}
<input type="submit" name="older" value="Older">
{% endif %}
</form>
In my view.py I pass in the tag plus other information in a render_to_response, but I'm not sure how to/if I can reclaim it while handling the buttons.
render_to_response('item/view.html', {'photo':photo, 'tag':tag, 'related_tags': related_tags, 'related_photos': related_photos, 'has_newer': has_newer, 'has_older': has_older}, context_instance=RequestContext(request))
Here's the view.py code for processing the buttons:
if 'newer' in request.GET:
if has_newer:
return HttpResponseRedirect('/gallery/view/%s/?tag=%s'%(newer[1].id, tag))
else:
return HttpResponseRedirect('/gallery/')
if 'older' in request.GET:
if has_older:
return HttpResponseRedirect('/gallery/view/%s/?tag=%s'%(older[1].id, tag))
else:
return HttpResponseRedirect('/gallery/')
<form action="/gallery/view/{{ photo.id }}/" method="get">
{% if has_newer %}
<input type="submit" name="newer" value="Newer">
{% endif %}
<!--This will append a tag parameter with given value to the querystring -->
<input type="hidden" name="tag" value="{{ tag }}">
<img src="{{ photo.photofile.url }}">
{% if has_older %}
<input type="submit" name="older" value="Older">
{% endif %}
</form>
Note that the query string is removed from action (as it won't be used) and the older and newer parameters will still be sent along.

Customizing django-comments

So, I'm using django.contrib.comments. I've installed it OK but rather than the unwieldy default comment form, I'd like to use a custom form template that just shows a textarea and submit button.
The rationale behind this is that user only see the form if they area already authenticated, and I'd like the keep the form simple and pick up their username etc automatically.
I've implemented a custom form, but am getting an error when I try to submit it.
Here's what I have in my template for the page with the comment form (entry is the object passed from the view):
{% load comments %}
{% render_comment_form for entry %}
And here's my HTML in /templates/comments/form.html:
{% if user.is_authenticated %}
<p>Submit a comment:</p>
<form action="/comments/post/" method="post">
<textarea name="comment" id="id_comment" rows="2" style="width: 90%;"></textarea>
<input type="hidden" name="options" value="{{ options }}" />
<input type="hidden" name="target" value="{{ target }}" />
<input type="hidden" name="gonzo" value="{{ hash }}" />
<input type="hidden" name="next" value="{{ entry.get_absolute_url }}" />
<span style="float:right;"><input type="submit" name="post" value="Add"></span>
</form>
{% else %}
<p>Please log in to post a comment.</p>
{% endif %}
It renders okay initially, but when I try to submit the comment form, I get the following Django error:
Comment post not allowed (400)
Why: Missing content_type or object_pk field.
Can anyone help?
The comment model uses a generic foreign key to map to the object for which the comment was made such as a blog entry. These are required hidden fields included in the standard comment form.
From django.contrib.comments.models
...
class CommentSecurityForm(forms.Form):
"""
Handles the security aspects (anti-spoofing) for comment forms.
"""
content_type = forms.CharField(widget=forms.HiddenInput)
object_pk = forms.CharField(widget=forms.HiddenInput)
...
If you haven't changed the form class and only want to change the html template then you can include these fields by adding a for loop over all the hidden fields.
{% for hidden in form.hidden_fields %}
{{ hidden }}
{% endfor %}
Fixed the problem by copying from Theju's app - in particular, see Joshua Works' comment on part 2.