django multi form and file field - django

I am currently using several differences forms on a single view. I am able to fill my forms but when I submit one of them, it seems that my form is invalid. I displayed the request.POST (it contains all my information) and my form (it contains my information except files parts.)
Could you explain me how to correct it?
Could it be linked to my models?
(I am using bootstrap 3 through django)
my view :
def view_addfiles(request):
try:
print(request.POST)
except:
{}
if request.method == 'POST' and 'search' in request.POST:
print("recherche")
recherche=searchbar(request.POST, prefix='search')
if recherche.is_valid():
print("recherche")
else :
recherche=searchbar(prefix='search')
if request.method == 'POST' and 'film' in request.POST:
print("film")
addfilm=Addfilms(request.POST,request.FILES, prefix='film')
print(addfilm)
if addfilm.is_valid():
print("film")
return redirect(view_accueil, inscription=3)
else :
print("dfsd")
addfilm=Addfilms(prefix='film')
if request.method == 'POST' and 'serie' in request.POST:
print("serie")
addserie=Addseries(request.POST,request.FILES, prefix='serie')
if addserie.is_valid():
print("serie")
return redirect(view_accueil, inscription=3)
else :
addserie=Addseries(prefix='serie')
return render(request, 'menuAjout.html',locals())
my html :
<form action="{% url "add_files" %}" method="post">
{% csrf_token %}
{{ recherche.as_p }}
<input type="submit" id="validation" name="search"/>
</form>
<div id="films">
{% load bootstrap3 %}
{% bootstrap_css %}
<form action="{% url "add_files" %}" method="post">
{% csrf_token %}
{% bootstrap_form addfilm %}
{% buttons %}
<button type="submit" class="btn btn-primary" id="submitbutton" name="film" value="submit">
{% bootstrap_icon "star" %} Ajouter
</button>
{% endbuttons %}
</form>
</div>
<div id="series">
<form action="{% url "add_files" %}" method="post">
{% csrf_token %}
{% bootstrap_form addserie %}
{% buttons %}
<button type="submit" class="btn btn-primary" id="submitbutton" name="serie">
{% bootstrap_icon "star" %} Ajouter
</button>
{% endbuttons %}
</form>
</div>
my forms :
class Addseries(forms.ModelForm):
class Meta:
model = series
exclude = ('nbTelechargement','datedepot')
class Addfilms(forms.ModelForm):
class Meta:
model = series
exclude = ('nbTelechargement','datedepot')
class searchbar(forms.Form):
motclef=forms.CharField(max_length=15,widget=forms.TextInput(attrs={'placeholder': 'Search...','style':'background :#ededef url("/static/image/search.png") no-repeat;background-size: auto 90%;'}))
categorie=forms.ChoiceField(choices=(('films', 'films'),
('séries', 'séries'),
('jeux', 'jeux'),
('logiciels', 'logiciels'),
('livres', 'livres'),
('musiques', 'musiques')))

I see several things:
It's not a Django issue but a HTML one:
When a user submits a form, he/she submits only form.
Django receives in request.POST only the data sent by one form.
Your forms share the same fields' names.
Addseries.nbTelechargement and Addfilms.nbTelechargement will have the same key in request.POST

I just forgot to add enctype="multipart/form-data" in my form balise.
My request.FILES was empty because of that.
So my form was unvalid because of that.

Related

My django form is not working when i iterate through it using for loop

Basically if I tried to use this code
{% for field in form %}
<div class="input">
<label for="" class="labelinput">{{field.label}}</label>
{{field}}
</div>
{% endfor %}
the form data wont make it pass is_valid().But it renders out the form fine. and if I use this code
<form action="" method="post"> {% csrf_token %}
{{form}}
<input type="submit" value="">
it worked perfectly fine. How do I get the first code to work because I want to add classes between the label and the input field
and here's my view
def booklist_view(request):
bkff = BookListForm()
if request.method == 'POST':
bkff = BookListForm(request.POST)
if bkff.is_valid():
bkff.save()
bkff = BookListForm()
context = {
'form': bkff,
}
return render(request, 'booklist1st/booklist.html', context)
Please try this.
views.py
def booklist_view(request):
form = BookListForm(request.POST or None)
if request.method == 'POST':
if form.is_valid():
form.save()
context = {'form': form }
return render(request, 'booklist1st/booklist.html', context)
Here we render field according according to field type(hidden_fields,visible_fields).
html template:
<form method="post">
{% csrf_token %}
{% for hidden in form.hidden_fields %}
{{ hidden }}
{% endfor %}
{% for field in form.visible_fields %}
<div class="input">
{{field.label}}
{{field}}
</div>
{% endif %}
<input class="btn btn-primary" type="submit" name="add_book" value="Save and add book" />
</form>
You need to specify each field relate data like for=, id=, etc. To have maximum control over how your form is rendered, specify each field and control its style, for example, as we can't see your Form definition, this is an example on how it would be for a title field:
<form method="post">{% csrf_token %}
{# Include the hidden fields #}
{% for hidden in form.hidden_fields %}
{{ hidden }}
{% endfor %}
{# Include the visible fields #}
{{ form.non_field_errors }}
{{ form.title.errors }}
<label for="{{ form.title.id_for_label }}">Title</label>
{{ form.title }}
{% if form.title.help_text %}
<small id="titleHelp">{{ form.title.help_text|safe }}</small>
{% endif %}
</div>
<input class="btn btn-primary" type="submit" name="add_book" value="Save and add book" />
</form>
<form method="post">
{% csrf_token %}
{% for hidden in form.hidden_fields %}
{{ hidden }}
{% endfor %}
{% for field in form.visible_fields %}
<div class="input">
<label for="" class="label">{{field.label}}</label>
{{field}}
</div>
{% endfor %}
<input class="btn btn-primary" type="submit" name="add_book" value="Save and add book" />
</form>
View.py
from django.views.decorators.csrf import csrf_protect
#csrf_protect
def booklist_view(request):
bkff = BookListForm()
if request.method == 'POST':
bkff = BookListForm(request.POST)
if bkff.is_valid():
bkff.save()
context = {
'form': bkff,
}
return render(request, 'booklist1st/booklist.html', context)

Get an object id from HTML in in request.POST

I have an user with list of tasks that he can add. I want to give him ability to delete those tasks, or mark as done.
The problem is that my solution is working only when user has one task, because of non-unique id's problem
Is there any way to pass the id to html so that it will be easily accesible in views? Thank you!
This is my current code
{% for task in tasks %}
<form id='is_checked' method='POST' action="{% url 'mark_as_done'%}" enctype="multipart/form-data">
{% csrf_token %}
<div class="input-group-text">
<input type="hidden" id="id_checked" value="{{task.id}}" name = "id_checked">
</div>
</form>
<form class="input-group" action="{% url 'delete_task'%}" method='POST' enctype="multipart/form-data">
{% csrf_token %}
<div class="input-group-prepend">
<div class="input-group-text">
<input onChange="document.getElementById('is_checked').submit()" type="checkbox" {% if task.is_done %}checked{% endif %}>
</div>
</div>
<h7 type="text" class="form-control">{{task}}</h7>
<input type="hidden" id="id" value="{{task.id}}" name = "id">
<button type="submit" class="input-group-append btn btn-danger">Delete</button>
</form>
{% endfor %}
And in views:
def delete_task(request):
if request.method == 'POST':
task = Task.objects.get(pk=request.POST['id'])
task.delete()
return redirect('tasks')
#login_required()
def mark_as_done(request):
if request.method == 'POST':
task = Task.objects.get(pk=request.POST['id_checked'])
task.is_done = True
task.save()
return redirect('tasks')```

how to process submit on django-tables2 with a class View with FilterView mixin

I have a django-tables2 FilterView.
The filter is templated in a form:
{% if filter %}
<form action="" method="get" class="form form-inline">
{% bootstrap_form filter.form layout='inline' %}
{% bootstrap_button 'filter' %}
</form>
{% endif %}
I have added a checkbox field to each row, and I have the table in a form:
<form action="table_selection" method="get" class="form form-inline">
{% csrf_token %}
{% render_table table 'django_tables2/bootstrap.html' %}
<button class="btn btn-primary red" type="submit" >Submit Rows</button>
</form>
When I submit, I get logging messages like:
GET /three_pl/threepl_fulfilments_filter/table_selection?csrfmiddlewaretoken=...
&select_row=198&select_row=158&select_row=159
so the select_rows are very interesting.
But I am lost with the class view, I can't grapple with how to process the form submission.
This is my view:
class FilteredThreePLFulfimentsView(SingleTableMixin,FilterView):
table_class = ThreePL_order_fulfilmentsTable
model = ThreePL_order_fulfilments
template_name = "three_pl/ThreePLFulfilmentsFilter.html" #three_pl/templates/three_pl/ThreePLFulfilmentsFilter.html
filterset_class = ThreePLFulfilmentsFilter
Answer: set up a url watching for /table_selection.
Make it before the url for the table render.
... url(r'^threepl_fulfilments_filter/table_selection',views.three_pl_fulfilments_selection,name='threepl_fulfilments_selection'),
...
and in the view:
if request.method == 'GET':
try:
selected_rows = request.GET.getlist('select_row')

How to create one form with multiple buttons in the loop

It is my form in template,
I am creating multiple forms with two buttons in the loop for voting particular item
and i think it is ugly, how can i avoid that using only one form for all buttons?
{% for bill_item in bill_items %}
<form action="{% url 'bills:change_quantity' bill_item.id %}" method="post">
{% csrf_token %}
<button name="up"></button>
<button name="down"></button>
</form>
{% endfor %}
It is my action in the view
def change_quantity(request, bill_item_id):
bill_item = BillItem.objects.get(pk=bill_item_id)
if 'up' in request.POST:
bill_item.increase()
elif 'down' in request.POST:
bill_item.decrease()
bill_item.save()
return HttpResponseRedirect('/bills/')
How about moving bill_item.id to button? Can't test this at the moment, so please treat this as unchecked suggestion
Like:
<form action="{% url 'bills:change_quantity' bill_item.id %}" method="post">
{% for x_id,bill_item in enumerate(bill_items) %}
<button name={% x_id %} value="up"></button>
<button name={% x_id %} value="down"></button>

How insert 2 different forms on the same page in Django

I have to insert 2 forms in the same page:
1) Registration form
2) Login form
.
So if I use this in the views.py:
if request.method == 'POST':
form = registrationForm(request.POST)
if form.is_valid():
form.save()
return render_to_response('template.html', {
'form': form,
})
I will get error by submitting one of two forms.
How can I distinguish the 2 forms submitting in the views ?
You can also do like this,
<form method='POST'>
{{form1.as_p}}
<button type="submit" name="btnform1">Save Changes</button>
</form>
<form method='POST'>
{{form2.as_p}}
<button type="submit" name="btnform2">Save Changes</button>
</form>
CODE
if request.method=='POST' and 'btnform1' in request.POST:
do something...
if request.method=='POST' and 'btnform2' in request.POST:
do something...
You can submit two forms on the same page... but the action that each form calls (i.e. the view function that will process each form) should probably be different. That way, you won't have to try and distinguish the forms.
e.g. On your page:
<form id="login_form" action="{% url app.views.login %}" method="post">
...form fields...
</form>
<form id="registration_form" action="{% url app.views.registration %}" method="post">
...form fields...
</form>
And so, in views.py, you'll have a login() view function and a registration() view function that will handle each of those forms.
<form action="Page where u want to post the data" method="post">
<input name="edit" type="submit" value="Edit Client">
<input name="delete" type="submit" value="Delete Client">
</form>
just Give different names to the buttons.
if request.method == "POST" and 'edit' in request.POST:
/ Do /
if request.method == "POST" and 'delete' in request.POST:
/Do /
You can post both forms to same url too:
forms in template are like this:
<form method="post" action="/profile/">
{% for field in firstform %}
<div class="mb10">
<div class="fl desc">{{ field.label_tag }}<br />
<div class="fr">{{ field }}{{ field.errors }}</div>
<div class="clear"></div>
</div>
{% endfor %}
{% for field in secondform %}
<div class="mb10">
<div class="fl desc">{{ field.label_tag }}<br /><</div>
<div class="fr">{{ field }}{{ field.errors }}</div>
<div class="clear"></div>
</div>
{% endfor %}
<a class="submit fr" href="#""><img src="{{ MEDIA_URL }}img/save.png" /></a>
</form>
and just handle them like this in view:
if request.method == 'POST':
firstform = ProfileForm(request.POST, request.FILES, instance=profile)
secondform = UserForm(request.POST, instance=request.user)
and then do stuff with firstform&secondform.
You can have both forms posting to the same URL and have a hidden input with name set to login or registration and sort that out on the server
You can do the Registration and Login POST to different urls so each POST will be handled by corresponding view