I have a Django application and want to display multiple choice checkboxes in a user's profile. They will then be able to select multiple items.
But I am not able to save the form that is created. Can anyone help?
My models.py looks like this:
class multiChoice(models.Model):
user=models.ForeignKey(User)
Options = (
("AUT", "Australia"),
("DEU", "Germany"),
("NLD", "Neitherlands")
)
Countries = models.ManyToManyField(Choices,choices=Options)
User.multiChoice=property(lambda u:multiChoice.objects.get_or_create(user=u)[0])
forms.py:
class multiChoiceForm(forms.Form):
Countries = forms.ModelMultipleChoiceField(queryset=Choices.objects.all(), required=False, widget=forms.CheckboxSelectMultiple)
class Meta:
model=multiChoice
fields=("Countries")
views.py:
def multiChoice_v1(request):
args = {}
args.update(csrf(request))
if request.method == 'POST':
form = multiChoiceForm(request.POST)
if form.is_valid():
countries = form.cleaned_data.get('countries')
countries.save()
form.save_m2m()
return HttpResponseRedirect('/accounts/loggedin/')
else:
form=multiChoiceForm()
args={}
args.update(csrf(request))
args['form']=form
return render_to_response('editprofile_v2.html', args)
urls.py - snippet of the multi-choice view alone:
url(r'^accounts/profile_v2/$', 'guitarclubapp.views.multiChoice_v1'),
editprofile_v2.html:
<html>
<form method='post'>{% csrf_token %}
<label> Countries </label>
<select name="Countries" id="Countries" class="multiselect" multiple="multiple">
<option value="AUT" selected="selected">Austria</option>
<option value="DEU" selected="selected">Germany</option>
<option value="NLD" selected="selected">Netherlands</option>
</select>
<input type='submit' value='submit'>
</form>
</html>
Is there anything that I am missing out (or) have done anything wrong?
Should I change the way I am defining my model?
Any help or references would be greatly appreciated.
Thanks in advance.
Related
So i'm trying to do a filter with django, to filter the items on the main page. A little context:
An item can be assigned to a user or not. I want a filter, to see what items are assigned and which items aren't.
This is my function in views.py:
class ItemsView(ListView):
template_name = 'inventory/items.html'
context_object_name = 'items_list'
def get_queryset(self):
if (self.request.user.is_authenticated):
if self.request.method == "get":
searched = self.request.GET.get('searched')
if searched == "None":
return Item.objects.filter(assigned_user__isnull=True, company=getCompany(self.request.user))
else:
return Item.objects.filter(assigned_user__isnull=False, company=getCompany(self.request.user))
else:
return Item.objects.filter(company=getCompany(self.request.user))
And this is from my items.html:
<form method="post" action="/items">
{% csrf_token %}
<select name="item_filter">
<option value="None">Not Checked In</option>
<option value="Checked_In">Checked In</option>
</select>
<input type="submit" value="filter">
</form>
So basically what i want is, that the user can pick one of the two choices in the dropdown-menu, and the items should be listed based on the choice he made.
When i use this form and click the submit button, the screen gets white and in my console, the error
Method Not Allowed (POST): /items/ appears. Has this something to do with the fact i'm using the generic.ListView for my view?
Thank you
in list view is POST not allowed. But you dont need it:
In template:
<form action="/items">
<select name="item_filter">
<option value>Not Checked In</option>
<option value="Checked_In">Checked In</option>
</select>
<input type="submit" value="filter">
</form>
in view:
class ItemsView(ListView):
... # any staff
def get_queryset(self):
query = {'company':getCompany(self.request.user)}
if (self.request.user.is_authenticated):
query['assigned_user__isnull'] = bool(self.request.GET.get('item_filter'))
return Item.objects.filter(query)
I've got a problem with django with handling forms : I created a form with 2 fields, and I associated it to my view, but it tells me that my fields are undefined. Could you explain me please ?
I created a form in my index.html :
<form action="/addUser" method="post">
{% csrf_token %}
<label> Name of the Employee : <input type="text" name="employeeName", id="employeeName"/> </label>
<label> Email of the Employee : <input type="email" name="employeeEmail", id="employeeEmail" /> </label>
<button class="btn btn-primary" type="submit">Add User</button>
</form>
Then I created in views.py
def addUser(request):
if request.method == 'POST':
form = CreationUserForm(request.POST)
newEmployee = Employee()
newEmployee.name = form[employeeName]
newEmployee.email = form[employeeEmail]
newEmployee.save()
return HttpResponseRedirect(reverse('app:home'))
And then I created in forms.py
class CreationUserForm(forms.Form):
employeeName = forms.CharField(label='employeeName', max_length=254)
employeeEmail = forms.CharField(label='employeeEmail', max_length=254)
So I don't understand why I get this error : name 'employeeName' is not defined
For my point of view it is...
I tried with form.employeeName too, but it considered as a non existant attribute.
Thank you for helping :)
In your addUser method, both the employeeName and employeeEmail are variables, which are not defined. You want to be accessing the keys via the strings.
def addUser(request):
if request.method == 'POST':
form = CreationUserForm(request.POST)
newEmployee = Employee()
newEmployee.name = form['employeeName']
newEmployee.email = form['employeeEmail']
newEmployee.save()
return HttpResponseRedirect(reverse('app:home'))
also a Django suggestion - before accessing the attributes of the form, it is often useful to check that the input is valid by calling if form.is_valid() as defined here: https://docs.djangoproject.com/en/2.2/ref/forms/api/
A have a field in model (name model is Users_data):
bir_date = models.DateField(verbose_name="")
And form which represents model:
class Form_registration (ModelForm):
class Meta:
model = Users_data
in html:
<form name="registration" method="post" action="save_data_user/">
{% csrf_token %}
{{ form_registration.as_p }}
<input type="submit" value="SignUp">
</form>
View which saves form:
def saves_data_user_on_registration (request):
if request.method == 'POST':
c = {}
c.update(csrf(request))
form_user_data = Form_registration(request.POST, request.FILES)
if form_user_data.is_valid():
print form_user_data.errors
form_user_data.save()
return render_to_response('see_you_later.html', c, context_instance=RequestContext(request))
else:
print form_user_data.errors
return render_to_response('error.html', c, context_instance=RequestContext(request))
I can save simple data in form.
But I need save a data in drop-down list from html in field from my model Users_data.
<select name="DateOfBirth_Month">
<option>Month</option>
<option value="1">January</option>
<option value="2">February</option>
...
<select id="cd-dropdown" class="cd-select">
<option value="-1" selected>Day</option>
<option value="1">01</option>
<option value="2">02</option>
...
<select name="DateOfBirth_Year">
<option>Year</option>
<option value="2011">2011</option>
<option value="2010">2010</option>
<option value="2009">2009</option>
...
And I don't understand how I can to connect drop-down list with my form or model.
Thanks for answers.
You need to define a widget and set it for the DateField using widgets on the Meta class.
A good example of the particular widget that splits year, month and day into separate dropdowns can be found in Django documentation, see DateSelectorWidget:
class Form_registration (ModelForm):
class Meta:
model = Users_data
widgets = {'bir_date': widgets.DateSelectorWidget()}
This code assumes you've created a widgets.py module with DateSelectorWidget class inside.
Another good widget for the task is django.forms.extras.widgets.SelectDateWidget:
Wrapper around three Select widgets: one each for month, day, and
year.
Also see:
Django SelectDateWidget to show month and year only
django-datetime-widget
Hope that helps.
The answer is to use a choices attribute for your DateField in the model.
Here is how to do it: https://docs.djangoproject.com/en/dev/ref/models/fields/
i have an custom form , whenever i fetch the form values to save in the database than it display an error ( applicationform() got an unexpected keyword argument 'job_title' ) and the values are not save in the table.
views.py :-
def applicationvalue(request):
if request.method == 'POST':
getjobtitle = request.POST['jobtitle']
getintable = applicationform(job_title=getjobtitle)
getintable.save()
print getjobtitle
return HttpResponse(getintable)
else:
return render_to_response('registration/applicationform.html')
my form is :-
<form method="POST" action="#" class="form-horizontal" id="applicationform" name="appform">
<input type="text" id="u_jobtitle" class="input-xlarge" name="jobtitle" value=" " />
<button class="btn btn-gebo" type="submit" name="usubmit">Save changes</button>
whenever i fetch the values from form to save the values in table field " job_title " than it will display an error :-
applicationform() got an unexpected keyword argument 'job_title'
Change input field name to job_title in your html
<input name="job_title" type="text" id="u_jobtitle" class="input-xlarge" value=" " />
-------------^ changed
and then in view do
def applicationvalue(request):
if request.method == 'POST':
#Dont need this
#getjobtitle = request.POST['jobtitle']
#---------------------------Use request.POST
getintable = applicationform(request.POST)
getintable.save()
print getjobtitle
return HttpResponse(getintable)
else:
return render_to_response('registration/applicationform.html')
It will be better if you use same form to render html instead of hand coding it.
The applicationform constructor should take the request.POST as argument.
But it seems to me that you are not using django forms in the "right" way. I think that your view doesn't follow the django philosophy for using form.
In your case, you should have a model:
from django.db import models
class Application(models.Model):
job_title = models.CharField(max_length=100)
Based on this model, you can declare a ModelForm:
from django import forms
from .models import ApplicationModel
class ApplicationForm(forms.ModelForm):
class Meta:
model = ApplicationModel
fields = ('job_title',)
Then you can use this form in your view
def applicationvalue(request):
if request.method == 'POST':
form = ApplicationForm(request.POST)
if form.is_valid():
#This is called when the form fields are ok and we can create the object
application_object = form.save()
return HttpResponse("Some HTML code") # or HttResponseRedirect("/any_url")
else:
form = ApplicationForm()
#This called when we need to display the form: get or error in form fields
return render_to_response('registration/applicationform.html', {'form': form})
finally you should have a registration/applicationform.html template with something like:
{% extends "base.html" %}
{% block content %}
<form action="" method="post">{% csrf_token %}
<table>
{{form.as_table}}
</table>
<input type="submit" value="Add">
</form>
{% endblock %}
I hope it helps
I used this code previously it worked fine and i was suggested to use ModelForm by another member, it did make sense to use the form.is_valid() function etc.. so thought of giving it a try.
I went through some other examples on the internet but mine does not seem to work for some reason, or may be I am not doing it right, I get the following when I print the form in the view, and it goes to the else statement, so my form does not get saved
<input id="id_product" type="text" name="product" value="aassddf" maxlength="250" />
FAIL
My model.py
from django.db import models
from django.forms import ModelForm
class Category(models.Model):
name = models.CharField(max_length=250)
def __unicode__(self):
return self.name
class Product(models.Model):
category = models.ForeignKey(Category)
product = models.CharField(max_length=250)
quantity = models.IntegerField(default=0)
price = models.FloatField(default=0.0)
def __unicode__(self):
return self.product
class ProductForm(ModelForm):
class Meta:
model = Product
My views.py
from models import *
from django.shortcuts import render_to_response
from django.http import HttpResponseRedirect
def index(request):
...
...
def add_product(request):
if request.method == 'POST':
form = ProductForm(request.POST)
print form['product']
if form.is_valid():
form.save()
return HttpResponseRedirect('/product')
else:
print 'FAIL'
return HttpResponseRedirect('/product')
My html
<form method="post" action="add_product/">
{% csrf_token %}
<label for="category">Category</label>
<select name="category" id="category">
{% for category in category_list %}
<option> {{ category.name }} </option>
{% endfor %}
</select>
<label for="product">Product</label>
<input type="text" name="product" id="product">
<label for="quantity">Quantitiy</label>
<input type="text" name="quantity" id="quantity">
<label for="price">Price</label>
<input type="text" name="price" id="price">
<input type="submit" value="Add New product" id="create">
</form>
Is there a better way i could save the data, using ModelForms ??
Thanks in advance for the help.
You should read the documentation. If the form is not valid, it will have a whole set of errors associated with it, which will tell you exactly why. But you just throw that away, and redirect to /product. The docs show exactly how to redisplay the form with the errors.
Also you should not write HTML form field tags directly in your template: use the form object from the view - {{ form.product }}, etc - as these will be repopulated with the appropriate values on redisplay.
Thanks to Daniel Roseman and Anuj Gupta I think I finally re-worked on my code on got it working in a standard way so it will generate the html form and validate errors.
So for anyone else who is trying to work django forms here is the code I worked on.
My model.py is was almost the same one i posted on the question but i removed
class ProductForm(ModelForm):
class Meta:
model = Product
I created a new form.py here is the code-
from django import forms
from models import Category
class ProductForm(forms.Form):
# Put all my Categories into a select option
category = forms.ModelChoiceField(queryset=Category.objects.all())
product = forms.CharField()
quantity = forms.IntegerField()
price = forms.FloatField()
My views.py changed had a lot of changes -
def add_product(request):
success = False
if request.method == "POST":
product_form = ProductForm(request.POST)
if product_form.is_valid():
success = True
category = Category.objects.get(name=product_form.cleaned_data['category'])
product = product_form.cleaned_data['product']
quantity = product_form.cleaned_data['quantity']
price = product_form.cleaned_data['price']
new_product = Product(category = category, product = product, quantity = quantity, price = price )
new_product.save()
new_product_form = ProductForm()
ctx2 = {'success':success, 'product_form':new_product_form}
return render_to_response('product/add_product.html', ctx2 , context_instance=RequestContext(request))
else:
product_form = ProductForm()
ctx = {'product_form':product_form}
return render_to_response('product/add_product.html', ctx , context_instance=RequestContext(request))
Finally in my html page i used {{ product_form.as_p }} so it created the forms dynamically
{% if success %}
<h3> product added successfully </h3>
{% endif %}
<form method="post" action=".">
{% csrf_token %}
{{ product_form.as_p }}
<input type="submit" value="Add New product" id="create">
<input type="reset" value="reset" id="reset">
</form>
This may not be the perfect solution, but for a starter like me this sounds good, and at times you just get lost while reading the docs lol, hope it helps some one.
Cheers
Try:
<form method="post" action="add_product/">
{% csrf_token %}
{{ form.as_p }}
</form>
in your template, instead of hand-coding the form's input tags. This shortcut will generate the form html for you, as well as print validation errors.
Make sure you return the form object to the template when:
There is no request.POST (form has not been submitted)
form.is_valid() fails (form has validation errors)
Of course, this is only to get you started. You really should read the docs