How to use multiple forms in Django 2.1? - python

Sorry for asking similar questions, but other similar questions/answers do not help me with Django 2.
Question:
I have two actions, one is to show some data as a table.
In the second form, I edit this data and will save it as a table using Django in the database. Here is some code:
simple_upload.html
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
<input type="file" name="myfile" value="formOne">
<button class="btn btn-primary" type="submit">Upload</button>
</form>
second form:
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
<input type="hidden" name="mytable" value="formTwo">
<table class="table" border="1" id="tbl_posts">
<thead>
<tr>
...
</tbody>
</table>
<input type="submit" value="Submit">
</form>
views.py
def simple_upload(request):
if request.method == 'POST':
...
if request.is_ajax():
return render(request,
'project/simple_upload.html',
{'section': 'project', 'lines': zipped})
return render(request,
'project/list.html',
{'section': 'project', 'lines': zipped})
return render(request, 'project/simple_upload.html')
urls.py:
urlpatterns = [
...
path('', views.simple_upload, name='list'),
...
]
list.html:
...
{% include "project/simple_upload.html" %}
...
In this case, only the first form works, the second one fails.
Question 1: Can I do if request.method == 'POST' and formOne in request.POST:", I try but it does not react at all.
Question2: How can I write two methods and assign them using urls.py?

To show the data in a table, you can try Tables2 in Django, this might make things easier for you
Also in your case, you might need to make different views for different forms, Since both of them make a POST request, it will be difficult to differentiate.
You can easily do that by specifying action attribute in form tag.
Form 1
<form id="form1" method="post" action="view/for/form/1" enctype="multipart/form-data">
{% csrf_token %}
<input type="file" name="myfile" value="formOne">
<button class="btn btn-primary" type="submit">Upload</button>
</form>
Form 2
<form method="post" action = "view/for/form/2" enctype="multipart/form-data">
{% csrf_token %}
<input type="hidden" name="mytable" value="formTwo">
<table class="table" border="1" id="tbl_posts">
<thead>
<tr>
...
</tbody>
</table>
<input type="submit" value="Submit">
</form>
Later you can redirect using json responses to avoid refreshing the page
in your urls.py add
url('view/for/form/2', save_form, name='save'),
in your views.py
def save_form(request):
#your save logic using request.post
return redirect('your/current/url')

Related

Sending data from template to Django views via button

I'm trying to create a delete button in my template:
<button type="submit" class="btn btn-danger" value={{ instance.name }}> Delete </button>
And I want this button to submit that data in my views.py :
instance_client = compute_v1.InstancesClient()
if request.method == "POST":
instance = request.POST['data']
instance_client.delete(project='xxx', zone='xxx', instance=HERE_I_WANT_THE_DATA)
It's a script that will delete an instance from gcloud.
But I don't know exactly how to deliver the data from the template to views.py.
I'm using Bootstrap 5.
Hope I understand your question.
Template
<form action="{% url 'delete_function' item.id %}" method="POST">
{% csrf_token %}
Cancel
<input class="btn btn-sm btn-danger" type="submit" value="Delete">
</form>
Views
def deleteFunction(request, pk):
item = Model.objects.get(id=pk)
if request.method == "POST":
item.delete()
return redirect('/')
url
path('delete_function/<str:pk>', views.deleteFunction, name='delete_function')

Django : How to differentiate post requests from different pages that are coming to the same page?

I have two pages both containing form. However both the pages are sending post request to the same page. How do I differentiate which page has sent the request.
dummy.html(first page)
<form action="/nda" method='POST'>
{% csrf_token %}
<button type="submit" name="submit" id="submit" value="I Agree" target="_blank">I Agree</button>
<button onclick="window.open('/greeting')" target="_blank"> I Disagree </button></br>
</form>
This page redirects to nda page.
nda.html(second page)
This page also redirects to the same page.
<form action="/nda" method='POST'>
{% csrf_token %}
<button type="submit" name="submit" id="submit" value="I Agree" target="_self">I Agree</button>
<button onclick="window.open('/greeting')" target="_self"> I Disagree </button></br>
</form>
My question is, how do I differentiate in my view that from which page it was coming from the page dummy or the same page that was nda.
views.py
def nda(request):
if request.method=='POST' :
# if this is from dummy I want to do this
return render(request,'mainapp/nda.html',{'user':email.split('#')[0]})
if request.method=='POST' :
# if this is from same page that is nda I want to do this
return render(request,'mainapp/home.html')
I am unable to figure out, how do I handle both cases differently
If I understand your question properly,you can use the name attribute in your submit button
<button type="submit" name="submit1" id="submit" value="I Agree" target="_blank">I Agree</button
<button type="submit" name="submit2" id="submit" value="I Agree" target="_blank">I Agree</button
And in the views
def nda(request):
if request.method=='POST' and 'submit1' in request.POST :
# do something
return render(request,'mainapp/nda.html',{'user':email.split('#')[0]})
elif request.method=='POST' and 'submit2' in request.POST:
#do something else
...
How it works ?
You click on the submit button and the server is accessing ..
A button with type submit follows the "action" path specified in the form tag
That is, so that you have a request for different pages, you need to create an additional url, views and html
Example:
one_html.html
<form action="{% url your_app:name1 %}" method='POST'>
{% csrf_token %}
<button type="submit" name="submit" id="submit" value="I Agree" target="_blank">I Agree</button>
<button onclick="window.open('/greeting')" target="_blank"> I Disagree </button></br>
</form>
urls.py:
...
url(r'^' + app_name + 'some_path', views_one, name='name1'),
views.py:
def views_one(request):
if request.method=='POST':
# do something
Exapmle:
two_html.html
<form action="{% url your_app:name2 %}" method='POST'>
{% csrf_token %}
<button type="submit" name="submit" id="submit" value="I Agree" target="_blank">I Agree</button>
<button onclick="window.open('/greeting')" target="_blank"> I Disagree </button></br>
</form>
urls.py:
...
url(r'^' + app_name + 'some_path', views_two, name='name2'),
views.py:
def views_two(request):
if request.method=='POST':
# do something
The difference is that the action points to a different url and thus will be called different views

How do I render form ChoiceField images next to choices without breaking the form?

I am trying to render the images of the choices next to their respective choice. Attempting to do so will not save the form as valid so I have become lost at what to do. I've tried both methods below and I have no idea why one works and the other doesn't, could I get some tips?
#Form:
class ServerGroupForm(forms.Form):
OPTIONS = (
("pic1", "https://i.imgur.com/tMahp6U.png"),
("pic2", "https://i.imgur.com/b76nwsj.gif"),
("pic3", "https://i.imgur.com/qzEcfyX.png Lover"),
("pic4", "https://i.imgur.com/kdc7UF7.png"),
("pic5", "https://i.imgur.com/ynWJ13W.gif"),
("pic6!", "https://i.imgur.com/goHFWsp.png"),
("pic7", "https://i.imgur.com/b76nwsj.gif"),
("pic8", "https://i.imgur.com/KPgKm79.png"),
("pic9", "https://i.imgur.com/7KtEV1i.png"),
("pic10", "https://i.imgur.com/7KtEV1i.png"),
("pic11", "https://i.imgur.com/FXfo773.png")
)
servergroups = forms.MultipleChoiceField(widget=forms.CheckboxSelectMultiple, choices=OPTIONS)
#View:
def sendmessage(msg):
#Other code sends msg to user, not includes so this isn't long
def select_server_group(request):
form = ServerGroupForm(request.POST)
if form.is_valid():
servergroups = form.cleaned_data['servergroups']
sendmessage(msg=servergroups)
return redirect('/')
return render_to_response('webts3/selcectsgroup.html', {'form':form },
context_instance=RequestContext(request))
#HTML: Works but no icons
<section class="login">
<div class="titulo">Create a channel</div>
<form method="post" action="." enctype="multipart/form-data">{% csrf_token %}
<table border="0">
{{ form.as_table }}
</table>
<input type="submit" class="btn btn-block btn-danger" value="Submit" style="margin-top: 10px;">
</form>
</section>
#HTML: Icons but not working
<form method='post' action="." enctype="multipart/form-data">{% csrf_token %}>
<table>
{% for x,y in form.fields.servergroups.choices %}
<tr>
<td><input type="checkbox" name="{{ x }}" value="{{ x }}"><img src={{ y }}</img></td>
</tr>
{% endfor %}
</table>
<input type='submit' value='submit'>
</form>
The name attribute of the field should not be {{ x }}. It should be "servergroups".
Note you'd also need to have some logic that determines if the field is already selected, for when for example the form is being redisplayed after validation errors.

django-why this form is always invalid

i have created a form with minimal fields(for testing) , but it never enters form.is_valid()
Here is the minimal code
in the models.py
from django.db import models
class sample(models.Model):
field1=models.CharField(max_length=100)
field2=models.CharField(max_length=100)
in the forms.py
from django.forms import ModelForm
from app.models import sample
class someform(ModelForm):
class Meta:
model=sample
in the views.py
some imports
def index(request):
return render(request, 'app/index.html')
def contact(request):
if request.method=='POST':
form=someform(request.POST)
if form.is_valid():
field1=form.cleaned_data['field1']
field2=form.cleaned_data['field2']
return HttpResponse("valid")
else:
return HttpResponse("invalid")
else:
form=someform()
return HttpResponse("error")
The problem is , it never enters (if form.is_valid()) . Am i missing something ? please help
in the index.html
<html>
<body bgcolor="#2E9AFE">
<form action="contact" method="post" enctype="multipart/form-data">
{% csrf_token %}
<input type="text" id="field1" name="field1">
<input type="text" id="field2" name="field2">
<input type="submit" id="submit" name="submit">
</form></body></html>
First pass your form to index.html, when the request is not POST in views.py:
else:
form=someform()
return render(request, 'index.html', locals())
In template you should make it like this:
<form action="contact" method="POST" xmlns="http://www.w3.org/1999/html">
{% csrf_token %}
{{ form.as_p }}
<button type="submit" class="btn">Submit</button>
</form>
When receiving the POST query, Django is looking for the 2 fields of IDs id_field1 and id_field2, litteraly, thus your HTML is to be the following:
<html>
<body bgcolor="#2E9AFE">
<form action="contact" method="post" enctype="multipart/form-data">
{% csrf_token %}
<input type="text" id="id_field1" name="field1">
<input type="text" id="id_field2" name="field2">
<input type="submit" id="submit" name="submit">
</form>
</body>
</html>
Another solution is to use the {{ form.as_p }} or {{ form.as_table }} to render the inputs inside or tags automatically.
You could also add {{ form.non_field_errors }}, {{ form.field1.errors }}, and {{ form.field2.errors }} in your current HTML to display the form errors when validation fails.

Django comments. How back to page after validation error

Below there is my code. I don't know how to redirect back after some validation errors
Urls.py:
(r'^comments/', include('django.contrib.comments.urls')),
views.py:
def show_episode(request, episode) :
episode = get_object_or_404(Episode, pk=episode)
return render_to_response('episode.html', context_instance=RequestContext(request, {
'episode' : episode,
}))
episode.html:
<div class="subsection">
{% get_comment_form for episode as form %}
<table>
<form action="{% comment_form_target %}" method="post">
{% csrf_token %}
{{ form }}
<tr>
<td colspan="2" style="text-align: center">
<input type="submit" name="submit" value="Post">
<input type="submit" name="preview" value="Preview">
</td>
</tr>
<input type="hidden" name="next" value="{% url episode episode.id %}" />
</form>
</table>
</div>
<div class="subsection">{% render_comment_list for episode %}</div>
I want to come back to this form when there will be some errors.
I try, but I have an error: 'QueryDict' object has no attribute '_meta'
Code:
def comments(request) :
if request.method == 'POST' :
form = CommentForm(request.POST)
if (form.is_valid()) :
form.save()
return HttpResponseRedirect(request.POST['next'])
return HttpResponseRedirect('/')
Do it the other way around: process the form in the same view (that is, set <form action="", this way the user won't lose his inputs (as he would with a redirect).
You can still call the other view via this view, though. ( if request.method == 'POST')
When there was no Error, send a response.redirect to a success view.

Categories

Resources