I am trying to create a form and save data to database when the submit button is clicked. But the data is not getting saved to database. i dont get any error. I am django 1.11. I referred to few stackoverflow question and that answers doesnt solve my issue. Could someone help in fixing it? Thanks in advance.
model.py
from __future__ import unicode_literals
from django.db import models
class NameForm(models.Model):
your_name = models.CharField(max_length=200)
views.py
from __future__ import unicode_literals
from django.shortcuts import render
from django.http import HttpResponseRedirect, HttpResponse
from django.views import generic
from django.template.response import TemplateResponse
from home.models import NameForm
from .forms import NameForm
class NameView(generic.View):
model_class = NameForm
initial = {'key': 'value'}
template_name = 'home/name.html'
def get(self, request, *args, **kwargs):
model = self.model_class()
return render(request, self.template_name, {'model': NameForm})
def post(self, request, *args, **kwargs):
if request.method == 'POST':
form = NameForm(request.POST)
if form.is_valid():
return HttpResponseRedirect('thanks/')
if form.is_valid():
form.save()
else:
form = NameForm()
return render(request, 'name.html', {'form': form})
urls.py
from django.conf.urls import url
from . import views
app_name = 'home'
urlpatterns = [
url(r'^$', views.NameView.as_view(), name='name'),
url(r'^your-name/$', views.NameView.as_view(), name='name'),
url(r'^your-name/thanks/$', views.NameView.as_view(), name='name'),
]
home/name.html
<form action="your-name/" method="post">
{% csrf_token %}
<label for="your_name">Your name: </label>
<input id="your_name" type="text" name="your_name" value="{{ current_name }}">
<input type="submit" value="OK">
</form>
forms.py
from .models import NameForm
from django import forms
class NameForm(forms.Form):
your_name = forms.CharField(label='Your name', max_length=100)
class Meta:
model = NameForm
fields = ['your_name']
You'll get by much easier if you use the batteries included in Django. Here's a list of the fixes in the version below...
Don't reuse names. NameModel is a model, NameForm is a form. (However, you'd usually really elide Model from a model name – it's just that Name sounded like a silly name for a model...)
Use ModelForms when you're managing models. They automatically validate input against your models, let you save the models easily, etc.
Use the CreateView/UpdateView/FormView generic views to deal with model creation, updates, inputs, etc. No code needed, just configuration!
Don't template forms yourself. form.as_p will get you a barebones form; form.your_name would render that field, etc.
Just a fair warning: this is dry-coded, so there might be typos or other small silliness.
models.py
from django.db import models
class NameModel(models.Model):
your_name = models.CharField(max_length=200)
forms.py
from django import forms
class NameForm(forms.ModelForm):
class Meta:
model = NameModel
fields = ['your_name']
views.py
from django.views.generic import CreateView
from django.urls import reverse_lazy
from .models import NameModel
from .forms import NameForm
class NameView(CreateView):
model_class = NameModel
form_class = NameForm
success_url = reverse_lazy('name-thanks')
initial = {'your_name': 'value'}
template_name = 'home/name.html'
urls.py
from django.conf.urls import url
from django.views.generic import FormView
from .views import NameView
app_name = 'home'
urlpatterns = [
url(r'^$', NameView.as_view(), name='name'),
url(r'^your-name/thanks/$', TemplateView.as_view({'template_name': 'home/thanks.html'}), name='name-thanks'),
]
home/name.html
<form action="your-name/" method="post">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="OK">
</form>
That's beacuse you've been redirected (return HttpResponseRedirect('thanks/')) before save
Your version:
if form.is_valid():
return HttpResponseRedirect('thanks/')
if form.is_valid():
form.save()
else:
...
And the version you seek, with redirect only after form saving and removed redundant second form.is_valid() check:
if form.is_valid():
form.save()
return HttpResponseRedirect('thanks/')
else:
...
Related
So I'm creating a reporting app for my organization I want to be able to save the user that submits the report. Problem is if I use the models.ForeignKey(User,on_delete=models.PROTECT) method on my model I get a drop down for all the users which is not what I want.
models.py
class Report(models.Model):
id = models.UUIDField(primary_key=True,default=uuid.uuid1,editable=False)
department = models.ForeignKey(Company,null=True,on_delete=models.SET_NULL)
user= models.ForeignKey(User,on_delete=models.PROTECT)
submission_date= models.DateField(auto_now=True) #invisible to user
submission_time = models.TimeField(auto_now=True) #invisible to ,user
date = models.DateField(default=now,blank=False)
time = models.TimeField(default=now,blank=False,help_text="hh:mm:ss")
location = PlainLocationField()
building = models.ForeignKey(bld,null=True,on_delete=models.SET_NULL)
size = models.PositiveIntegerField()
notes = models.TextField(blank=True)
def __str__(self):
return f'{self.date} {self.time} ({self.company})
form.py
from django.forms import ModelForm, fields
from django.shortcuts import redirect
from django.urls.conf import include
from .models import Report
from django import forms
from location_field.forms.plain import PlainLocationField
class ReportForm(forms.ModelForm):
class Meta:
model = Report
fields = '__all__'
location = PlainLocationField()
def redirect():
return redirect("Report")
views.py
from django.forms import fields
from django.forms.forms import Form
from django.http import request
from django.http.request import HttpRequest, validate_host
from django.http.response import HttpResponse, HttpResponseRedirect
from django.shortcuts import render,redirect
from django.urls.base import reverse
from django.views.generic.base import TemplateView
from django.contrib.auth import authenticate, login
from django.contrib.auth.mixins import LoginRequiredMixin
# Create your views here.
from .forms import ReportForm
from .models import Report
from django.views.generic.edit import CreateView, UpdateView, DeleteView
class ReportCreate(LoginRequiredMixin,CreateView):
Template = "templates\reports\report.html"
model = Report
fields = '__all__'
def form_valid(self, form):
return super().form_valid(form)
def get_success_url(self):
return reverse('Report')
def home(request):
return render(request,"users/home.html")
EDIT:
templates/report_form.html
{% extends "base_generic.html" %}
<head>
</head>
<body>
{% block content %}
<form action="" method="post" onsubmit="return True">
{% csrf_token %}
<table>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<input type="hidden" name="user" value= "{{ request.user }}">
{{ form.as_table }}
{{ form.media }}
</table>
<input type="submit" value="Submit">
</form>
{% endblock %}
</body>
There's a few of ways to go about this.
You can add blank=True to user model field and assign the user when overriding the form_valid method:
def form_valid(self, form):
form.instance.user = self.request.user
form.instance.save()
return super(ReportCreate, self).form_valid(form)
Or, render the user form field as a hidden field and pre-populate it:
<input type="hidden" name="user" value="{{ request.user }}
For some reason I cannot get my Django form to render. I'm not sure what I'm missing.
I'm trying to get the class HomeForm(forms.Form) to render on the myaccount/change.html page and have been unsuccessful.
I'm new to Django so I might be missing a small detail somewhere but I thought I got everything covered from the djago documentation.
If anyone can help me out it would be gladly appreciated. Thanks!
users/forms.py
from django.contrib.auth.forms import UserCreationForm, UserChangeForm
from django import forms
from .models import CustomUser
class HomeForm(forms.Form):
post = forms.CharField()
your_name = forms.CharField(label='Your name', max_length=100)
class CustomUserCreationForm(UserCreationForm):
# job_title = forms.IntegerField(label='2 + 2', label_suffix=' =')
# yes = forms.IntegerField(required=True)
tos_check = forms.BooleanField(required=True, label='I have read and agree to the Terms of Service.')
age_check = forms.BooleanField(required=True, label='I am 21 years of age or older.')
class Meta(UserCreationForm.Meta):
model = CustomUser
fields = ('username', 'email')
help_texts = {
'username': '',
'email': '',
# 'password1': 'None',
# 'password2': 'Test'
}
class CustomUserChangeForm(UserChangeForm):
tos_checktwo = forms.BooleanField(required=True, label='I have read and agree to the Terms of Service.')
class Meta(UserChangeForm.Meta):
model = CustomUser
fields = ('username', 'email', 'tos_checktwo')
# class Meta:
# model = CustomUser
# fields = ('username', 'email', 'tos_check',)
users/views.py
from django.http import HttpResponse
from django.http import HttpResponseRedirect
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.shortcuts import redirect
from django.shortcuts import render
from django.template import loader
from django.urls import reverse_lazy
from django.views import generic
from django import forms
from .forms import CustomUserCreationForm
from .forms import HomeForm
def get_name(request):
# if this is a POST request we need to process the form data
if request.method == 'POST':
# create a form instance and populate it with data from the request:
form = HomeForm(request.POST)
# check whether it's valid:
if form.is_valid():
# process the data in form.cleaned_data as required
# ...
# redirect to a new URL:
return HttpResponseRedirect('/home/')
# if a GET (or any other method) we'll create a blank form
else:
form = HomeForm()
return render(request, 'myaccount/change.html', {'form': form})
class SignUp(generic.CreateView):
form_class = CustomUserCreationForm
success_url = reverse_lazy('login')
template_name = 'signup.html'
pages/urls.py
from django.urls import path
from django.urls import path, include
from django.conf.urls import url
from django.conf import settings
from . import views
from .views import HomePageView, MyAccountView, AboutPageView, PrivacyPageView, ContactPageView
urlpatterns = [
path('about/', AboutPageView.as_view(), name='about'),
path('privacy/', PrivacyPageView.as_view(), name='privacy'),
path('contact/', ContactPageView.as_view(), name='contact'),
path('', HomePageView.as_view(), name='home'),
path('myaccount/', MyAccountView.as_view(), name='myaccount'),
url('avatar/', include('avatar.urls')),
url('myaccount/', include('avatar.urls')),
]
templates/myaccount/change.html
{% extends 'base.html' %}
{% load static %}
{% block content %}
<form action="" method="post">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Submit">
</form>
{% endblock content %}
Sir, I don't see any problem in the code shared. But here is 2 hints :
check if in base.html, you have included the block content.
add print(form) before the return in the view to see what you get (the print result will be on the terminal not the browser)
edit :
You should add an url that calls the view :
in url add this line :
path('testform/', view.get_name, name ='get_name')
and then on your brower, test the url 127.0.0.1:8080/testform/
you will need to include {% block content %} and {% endblock %} tags in your base.html file.
When you "extend" the base template, these tags indicate where the extra content should be inserted.
see tte Template Inheritance
#AlouaniYounes Looks like on base.html the my account page was being directed somewhere else. I made the fix to base.html and problem solved. Thanks!
I have started leaning Django1.11 a few days ago, but I can't understand how can I render form using formset_factory.
Here is myproject/app/views.py file.
from __future__ import unicode_literals
from django.shortcuts import render
from django.http import HttpResponse, HttpResponseRedirect
from .forms import ArticleFormSet
def get_name(request):
form = ArticleFormSet()
return render(request, 'name.html', {'form' : form})
Here is app/forms.py file.
from django import forms
from django.forms import formset_factory
class ArticleForm(forms.Form):
title = forms.CharField()
pub_date = forms.DateField()
def ArticleFormSet(self):
ArticleFormSet = formset_factory(ArticleForm)
Here is name.html file.
<form action="/your-name/" method="post">
{% csrf_token %}
{{ form }}
<input type="submit" value="Submit" />
</form>
I have tried to render form on the browser, but exception has occurred like this.
ArticleFormSet() takes exactly 1 argument (0 given)
I can't figure out what's wrong.
You don't have to create a function for formset_factory. Remove the ArticleFormSet function and only this line is enough.
from django import forms
from django.forms import formset_factory
class ArticleForm(forms.Form):
title = forms.CharField()
pub_date = forms.DateField()
ArticleFormSet = formset_factory(ArticleForm)
I have a form that is updating text but not updating checkboxes in my database. The checkboxes are a boolean model in the database (postgres) where f is false and t is true. I've looked at a few other tutorials and tried to use multiple choice without much success.
I'll apologize ahead of time because I'm self taught in django and this is my first deplorable app.
Here is the forms.py module
from django import forms
from .model import parcels
class tableedit(forms.ModelForm):
class Meta:
model = parcels
fields = [
"some_number",
"boolean_checkbox_1",
"boolean_checkbox_2"
]
Here is the the model in model.py
from django.db import models
from django.contrib.postgres.fields import ArrayField
from django.core.urlresolvers import reverse
class TableName(models.Model):
name = 'table_name'
verbose_name = 'table_name'
some_number = models.CharField('some_number', max_length=30)
boolean_checkbox_1 = models.BooleanField('boolean_checkbox_1 ', max_length =1)
boolean_checkbox_2 = models.BooleanField('boolean_checkbox_2', max_length = 1)
# Returns the string representation of the model.
def __str__(self): # __unicode__ on Python 2
return self.name
def get_absolute_url(self):
return reverse("table_edit:view", kwargs={"id": self.id})
class Meta:
managed = True
db_table = 'table'
Here is my views.py
from django.shortcuts import render, redirect
from django.http import HttpResponse
from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse
from django.views.generic import UpdateView,View
from django.contrib import auth
from django.views.decorators.csrf import csrf_protect
from model import tableedit
from django.contrib.auth.decorators import login_required
from django import forms
import simplejson
from forms import tableedit
#login_required
#csrf_protect
def table_edit(request, p_id = None):
data = parcels.objects.get(id = p_id)
form = tableedit(request.POST or None, instance = data)
if form.is_valid():
instance = form.save(commit = False)
instance.save()
return HttpResponseRedirect(instance.get_absolute_url())
context = {
"some_number" : data.some_number,
"boolean_checkbox_1" : data.boolean_checkbox_1,
"boolean_checkbox_2" : data.boolean_checkbox_2,
"form":form}
return render(request, "static/table_edit.html", context)
Here is the form in the table_edit.html file
{% if next %}
<input type = "hidden" name="next" value= {% url 'table.view' table.id %} \>
{% endif %}
{{ form.as_p }}
<form action=next method="post">{% csrf_token %}
<input type="submit" value="Update Item" />
</form>
Your {{ form.as_p }} is not inside your html <form> tag. It's unlikely that any data is being sent to the server from that form.
I am a newbie to django framework and want to take values and save it to database. for this i used post method but when i check it is executing else part. I went through previous question on it but still found unsatisfying in my case.
Code is as follow:
#views.py
from django.shortcuts import render, render_to_response
from django.http import HttpResponse, HttpResponseRedirect
from .models import StudentInfo, History
from django.shortcuts import get_object_or_404, render
from .forms import Info
def index(request):
return HttpResponse("Hello, world")
def info(request):
if request.method == "POST":
the_form=Info(request.POST or None)
context={
"form": the_form
}
if form.is_valid():
form.save()
else:
return HttpResponse("It sucks")
return render(request, 'details.html', context)
#models.py
from __future__ import unicode_literals
from django.db import models
# Create your models here.
class StudentInfo(models.Model):
name=models.CharField(max_length=40, help_text="Enter Name")
reg_no=models.IntegerField(help_text='Enter your reg_no', primary_key=True)
email=models.EmailField(help_text='Enter email')
def __str__(self):
return self.name
class History(models.Model):
Reg_no=models.ForeignKey('StudentInfo', on_delete=models.CASCADE)
date=models.DateTimeField(auto_now=True)
def was_published_recently(self):
return self.date >= timezone.now() - datetime.timedelta(days=1)
#forms.py
from django import forms
from .models import StudentInfo, History
class Info(forms.ModelForm):
name= forms.CharField(label= 'Enter name')
reg_no= forms.CharField(label= 'Enter registration no.')
email= forms.EmailField(label= 'Enter email')
class Meta:
model= StudentInfo
fields= ['name', 'reg_no', 'email',]
#details.html
<h1>Enter the details</h1>
<form action="{% url 'auto:info' %}" method="post">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Go" />
</form>
if form.is_valid():
form.save()
You should use the_form instead of form since that's what you called the output of info(...)