The user enters the data in the form. But the data entered in the form doesn't get displayed in the Database.
views.py
def add(request):
if request.method=='POST':
form=FilesCreate(request.POST)
if form.is_valid():
form.save()
return render(request,'plagiarism/page1.html',{'form':FilesCreate()})
def add2(request):
if request.method=='POST':
form2=FilesCreate2(request.POST)
if form2.is_valid():
form2.save()
return render(request,'plagiarism/page2.html',{'form':FilesCreate2})
models.py
from django.db import models
class File1(models.Model):
#user=models.ForeignKey(User)
firstfile=models.CharField(max_length=1000, default="")
#secondfile=models.CharField(max_length=1000)
def __str__(self):
return self.firstfile
plagiarism/page1.html
<h1>Enter your first file</h1>
<form action="file2/" method="post">
{% csrf_token %}
{% for field in form %}
{{field}}
<input type="submit" value="Submit file1"/>
{% endfor %}
</form>
plagiarism/page2.html (displays page after clicking submit in page 1)
<h1>Enter your second file</h1>
<form action="plagiarism/file2/result/" method="post">
{% csrf_token %}
{% for field in form %}
{{field}}
<input type="submit" value="Get Results"/>
{% endfor %}
</form>
{% block h1 %}
{% endblock %}
<body>
plagiarism/page3.html (displays page after clicking submit in page 2)
<h1> Here is your Result </h1>
<h2>
{{data}}
</h2>
</body>
forms.py
from django.forms import ModelForm
from django import forms
from plagiarism.models import File1,File2
class FilesCreate(ModelForm):
class Meta:
model=File1
exclude=()
widgets={'firstfile':forms.Textarea(attrs={'cols':50,'rows':100})}
example.py
from django.shortcuts import render
def getresult(request):
data=95.5
return render(request,'plagiarism/page3.html',{'data': data})
urls.py
from django.conf.urls import url
from . import views
from . import example3
urlpatterns=[
url(r'^$',views.add,name='add'),
url(r'file2/$',views.add2,name='add2'),
url(r'file2/result/$',example3.getresult,name='getresult')
]
You seem to want a kind of wizard, where you process a form and it redirects you to the next, but you're not doing the basics of form processing well. For simple form handling, you can do this:
urls.py
from django.conf.urls import url
from . import views
from . import example3
urlpatterns=[
url(r'^$',views.add,name='add'),
url(r'file2/result/$', example3.getresult, name='getresult')
]
In the template, you are calling file2 with the form's action, but you really want to call the same page, to process the form with the add view:
plagiarism/page1.html
<h1>Enter your first file</h1>
<form method="post">
{% csrf_token %}
{% for field in form %}
{{field}}
{% endfor %}
<input type="submit" value="Submit file1"/>
</form>
Note the missing action attribute in the <form> element.
When you visit the root of the website, the add view will be called with a GET request. When you submit the form, the same add view will be called, with a POST request, which will then be processed:
views.py
def add(request):
if request.method == 'POST':
form = FilesCreate(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect(reverse('getresult'))
else:
form = FilesCreate()
return render(request,'plagiarism/page1.html',{'form': form})
Note the HttpResponseRedirect, which redirects to a new page on success, and the else, which creates an empty form for the first time you visit the page (i.e. request.method is not POST, it is GET). This way, if the form isn't valid, the last line will render it bound to the data that was submitted and display the errors.
This should get you the data into the database, which was your first goal. If you want to go to another form upon submission, you can redirect there (instead of the result page) and do the same as above in the view add2.
There used to be a Django Form Wizard, but you can see this project to do multi-step forms.
Related
views.py
def registerPage(request):
form = UserCreateForm()
if request.method=='POST':
form=UserCreateForm(request.POST)
if form.is_valid():
user=form.save(commit=False)
user.save()
return redirect('home')
return render(request,'base/signup.html',{'form':form})
model.py
class User(AbstractUser):
name = models.CharField(max_length=200,null=True)
email = models.EmailField(unique=True,null=True)
bio=models.TextField(null=True)
avatar = models.ImageField(upload_to='images/',null=True)
USERNAME_FIELD='email'
REQUIRED_FIELDS=['username']
forms.py
class UserCreateForm(UserCreationForm):
class Meta:
model = User
fields = ['name','email','password1','password2','bio','avatar']
htmltemplate
{% include 'main.html' %}
{% block content %}
<div>
<form method="POST">
{% csrf_token %}
{% for field in form %}
{{field.label}}
{{field}}
{% endfor %}
<input type="submit" value="Register" >
</form>
</div>
{% endblock content %}
when ever i try to sign up on html template it doesnt work but if i do it in admin panel it works how can i solve it ?
First of all, it is generally not recommended to mess with the default User model from django. Its better to create a Profile model with a OneToOneField relationship with the user.
Other than that, your issue lies with your form. Since you have avatar which is an ImageField you need to change your form in a way that it can accept FILES.
So what you need to do is change your form like this:
<form method="post" action="" enctype="multipart/form-data" >
When you are writing client-side code:
use multipart/form-data when your form includes any <input type="file"> elements.
In order to make your POST request valid, you need to also receive your FILES on your view. That can be done by changing your code to:
if request.method=='POST':
form=UserCreateForm(request.POST, request.FILES)
if form.is_valid():
....
When I click submit in the add tasks page, I get no response. The submit button is supposed to add tasks to the list in the tasks page. It does not show any errors and I'm not sure if its code is even running.
views.py:
from django.shortcuts import render
from django import forms
from django.urls import reverse
from django.http import HttpResponseRedirect
# Create your views here.
class NewTaskForm(forms.Form):
task = forms.CharField(label="New Task")
# Add a new task:
def index(request):
# Check if there already exists a "tasks" key in our session
if "tasks" not in request.session:
# If not, create a new list
request.session["tasks"] = []
return render(request, "tasks/index.html", {
"tasks": request.session["tasks"]
})
def add(request):
# Check if method is POST
if request.method == "POST":
# Take in the data the user submitted and save it as form
form = NewTaskForm(request.POST)
# Check if form data is valid (server-side)
if form.is_valid():
# Isolate the task from the 'cleaned' version of form data
task = form.cleaned_data["task"]
# Add the new task to our list of tasks
request.session["tasks"] += [task]
# Redirect user to list of tasks
return HttpResponseRedirect(reverse("tasks:index"))
else:
# If the form is invalid, re-render the page with existing information.
return render(request, "tasks/add.html", {
"form": form
})
return render(request, "tasks/add.html", {
"form": NewTaskForm()
})
add.html template:
{% extends "tasks/layout.html" %}
{% block body %}
<h1>Add Task:</h1>
<form action="{% url 'tasks:add' %}" method="post"></form>
{% csrf_token %}
{{ form }}
<input type="submit" value="Submit">
</form>
View Tasks
{% endblock %}
index.html:
***
{% extends "tasks/layout.html" %}
{% block body %}
<h1>Tasks:</h1>
<ul>
{% for task in tasks %}
<li>{{ task }}</li>
{% empty %}
<li>No tasks</li>
{% endfor %}
</ul>
Add a New Task
{% endblock %}
***
Your form element is closed out prematurely, so clicking the input probably doesn't do anything at all. If it somehow does, because you still have a closing </form> tag then it doesn't know where to send the POST to.
<form action="{% url 'tasks:add' %}" method="post"></form> <-- This
What I really want to do is , if a user click on "ADD more" button then a same form repeat itself and the values should store in database, if he/she doesn't click of that button then only the values from first form should be stored.
I am not able to get this, I just created a form , and a table in database for those details but can't loop though the form neither in data.
please help.
This is the form and the button:
This is the model.py code:
from django.db import models
class experience(models.Model):
company_name = models.CharField(max_length=100)
address = models.CharField(max_length=100)
startdate = models.Datefield(default = 01-01-2020)
lastdate = models.DateField(default = 01-01-2020)
profile = models.CharField(max_length=100)
description = models.TextField(max_length = 250)
This is the views.py code:
from django.shortcuts import render, redirect
import requests
from django.contrib.auth.models import User, auth
# Create your views here.
def profile(request):
return render(request, 'profile.html')
Unfortunately, there's no built-in way (as far as I know) in Django to do that without Javascript, but here's an approach:
HTML:
<div class="container" id="experiencesContainer">
<form method='POST' name='experienceForm'>
{{form.as_p}}
</form>
<form method='POST' name='experienceForm'>
{{form.as_p}}
</form>
<button type="button" id="addMoreButton">Add more</button>
<button type="submit">Save Changes</button>
</div>
Django POST method:
# Get a list of submitted forms
experiences = request.POST.getlist('experienceForm')
for experience in experiences:
# this is how you loop throuh every form
experience.get('company_name)
Your javascript something like:
// clonning his childs as well
let cloneForm = document.querySelector('form[name=experienceForm]').cloneNode(true);
document.querySelector('div#experiencesContainer').appendChild(cloneForm);
// see this https://www.w3schools.com/jsref/met_node_clonenode.asp
Of course this code is not tested but I've done this in several projects before, hope it works!
A simple way would be to request the same view from the "Add", just make sure your form view saves the data when request method is POST.
<form action="{% url 'your-form-url' %}" method="GET">
{% csrf_token %}
<input type="submit" value="Add">
</form>
one other way to repeat forms would be using formsets. Formsets allow you to repeat the same form 'extra' times. Check out the documentation for more about this.
def repeat_form(request):
ExpFormSet = formset_factory(ExperienceForm, extra=3)
#extra defines the no. of forms you want to display
if request.method == 'POST':
formset = ExpFormSet(request.POST, request.FILES)
if formset.is_valid():
# do something with the formset.cleaned_data
#loop through each form in the formser
for form in formset.cleaned_data:
obj = form.save()
else:
formset = ExpFormSet()
return render(request, 'exp_form.html', {'formset': formset})
The corresponding template should be:-
<form method="post">
{{ formset.management_form }}
{% for form in formset %}
{{ form.as_p }}
{% endfor %}
</form>
Make sure you add form.management_form. Using the combination of the above might solve your problem of taking and saving several inputs.
I am using Django and Postgresql as database. I have a HTML page with two fields name and item. I can save the data in the database by clicking on submit. But, I want to show the saved data from database in the HTML page. It means, whenever we load the page, it should show the existing saved data and after submitting new data, the list should be updated. Below is my python code.
models.py
from django.contrib.auth.models import User
from django.db import models
class AllocationPlan(models.Model):
name = models.CharField(max_length=50)
item = models.CharField(max_length=4096)
views.py
class HomePageView(TemplateView):
template_name = "index.html"
def post(self, request, **kwargs):
if request.method == 'POST':
form = AllocationPlanForm(request.POST)
if form.is_valid():
form.save()
return render(request, 'index.html', { 'form': AllocationPlanForm() })
forms.py
from django import forms
from django.forms import ModelForm
from homeapp.models import AllocationPlan
class AllocationPlanForm(ModelForm):
class Meta:
model = AllocationPlan
fields = "__all__"
index.html
<html>
<form method="post">{% csrf_token %}
Name:<br>
<input type="text" name="name" >
<br>
Item:<br>
<input type="text" name="item" >
<br><br>
<input type="submit" value="Submit"/>
</form>
{% for i in form %}
{{ i.name }}
{{ i.item }}
{% endfor %}
</html>
It is returning NONE
Forms in Django are not used to display lists of data. It's merely used to render / validate the form (<form> tag in html). See also the forms doc.
Furthermore, it seems like you're using the TemplateView incorrectly. The post method in your view is only called on a POST request. When you're just viewing the page normally, the template is rendered normally, but since you only add the data to the template in a POST request, the template does not receive a form parameter when loading the view normally (therefore defaulting to None).
According to the TemplateView documentation, you can add the context like so:
class HomePageView(TemplateView):
template_name = 'index.html'
def get_context_data(self, **kwargs):
context = super(HomePageView, self).get_context_data(**kwargs)
# Get the allocation plans from database. Limit to last 10. Adjust to your own needs
context['plans'] = AllocationPlan.objects.all()[:10]
context['form'] = AllocationPlanForm()
return context
def post(self, request, **kwargs):
form = AllocationPlanForm(request.POST)
if form.is_valid():
form.save()
# Handle rest of request here (for example, return the updated page).
As you can see, there is no need to check if request.method == 'POST' in your post method, because Django only calls this method on POST requests. See also dispatch in the docs
To render the data from your database you can now access them in your template as plans:
{% for plan in plans %}
{{ plan.name }}
{{ plan.item }}
{% endfor %}
In your HTML, there is also no need to manually create the form content:
<form method="post">
{% csrf_token %}
{{ form }}
<input type="submit" value="Submit" />
</form>
This will automatically create the HTML necessary for the form.
I'm new to django and I'm having a lot of trouble with forms.
I'm making a calculation-based tool and I need to be able to have an arbitrary number of inputs.
As a really basic example, let's say I want to make a calculator that will sum and subtract any number of inputs. Each number to be added or subtracted is in its own number field. Both the list of "adding" fields and the list of "subtracting" fields has its own "add another field" button.
For starters, here's something that adds two inputs (since I can't figure out how to implement even 1 "add another field button" or understand the answer to it).
views.py
from __future__ import unicode_literals
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render
from django.views.decorators.csrf import csrf_exempt
from .forms import AddForm
def _from_str(s):
try:
s = int(s)
except ValueError:
try:
s = float(s)
except ValueError:
pass
return s
#csrf_exempt
def web_adder(request):
if request.method == 'POST':
form = AddForm(request.POST)
# form = MyForm(request.POST, extra=request.POST.get('extra_field_count'))
if form.is_valid():
return web_adder_out(request, _from_str(form.cleaned_data['addend0']), _from_str(form.cleaned_data['addend1']))
else:
form = AddForm()
# form = MyForm()
return render(request, 'addercontent.html', {'form': form})
def web_adder_out(request, a, b):
return render(request, 'addercontentout.html', {'content':[a + b]})
forms.py
from django import forms
class AddForm(forms.Form):
addend0 = forms.CharField(label='first addend', max_length=100)
addend1 = forms.CharField(label='second addend', max_length=100)
addercontent.html
{% block content %}
<p>This is a web adder</p>
<form action="" method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit" class="btn btn-default">Enter</button>
</form>
{% endblock %}
addercontentout.html
{% block content %}
{% for c in content%}
Result: {{c}}
<br>
Return
{% endfor %}
{% endblock %}
Don't use Django for the field generation. I would do all of it via HTML. Run your setup that you currently have, and you should be able to look at the page source to see how the inputs are structured. Then you can manually write the form in HTML, with JavaScript adding fields in as needed.
Something like this? (not tested, I haven't implement add button)
forms.py
class CalcForm(forms.Form)
first = forms.IntegerField()
second = forms.IntegerField()
def add(self):
first = self.cleaned_data['first']
second = self.cleaned_data['second']
return first + second
views.py
def index(request):
if request.method == "POST":
form = CalcForm(request.POST)
if form.is_valid():
result = form.add()
return render(request, 'your_result_template.html', {'result': result})
else:
form = CalcForm()
return render(request, 'your_template.html', {'form': form})
your_template.html
{% block content %}
<p>This is a web adder</p>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit" class="btn btn-default">Enter</button>
</form>
{% endblock %}
your_result_template.html
{% block content %}
<p>Sum:</p>
<h2>{{ result }}</h2>
{% endblock %}
Edit: For field generation you may need javascript.
I don't know why you want to use django for this kind of app.