django-modelform can't bind post data - django

i have a problem with django modelform
here is the model:
class Comment(models.Model):
username=models.CharField(max_length=50)
email=models.EmailField()
content=models.TextField()
def __unicode__(self):
return unicode(self.username)
here is the modelForm:
class CommentForm(ModelForm):
class Meta:
model=Comment
in the view:
def comment(request):
response = HttpResponse()
f = CommentForm(request.POST)
if f.is_valid():
comment = f.save(commit=False)
response.write("1")
else:
response.write("0")
return response
form in templates:
<form action="/comment/add/" method="post">
{% csrf_token %}
<p>Username: <input type="text" name="username"></p>
<p>Your e-mail: <input type="text" name="email"></p>
<p>Content: <textarea name="content" rows="10" cols="50"></textarea></p>
<input type="submit" value="Submit">
</form>
the problem is f.is_valid() is always False.
but if i define a dict like this:
data={
'username':'test',
'email':'test#test.com',
'content':'test comment'
}
and put it in the modelform: f = CommentForm(data) after this, f.is_valid() will be True
i don't know why,anybody help me?

Make sure you have method="POST" attribute in <form> tag. And make sure you put {% csrf_token %} is within your form.

Related

Custom Form Field Render using UpdateView not Saving Data

I am trying to use custom HTML to render form field elements. However, now the data is not saving. The data is saving if I use the default form.as_p method.
Related template:
<!--DOES NOT SAVE DATA-->
<form action="" method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form.description }}
<input type="submit" value="Update"/>
</form>
<!--SAVES DATA-->
<form action="" method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Update"/>
</form>
Related UpdateView:
class ProfileEditView(UserPassesTestMixin, UpdateView):
model = Profile
form_class = ProfileCreateForm
template_name = 'update_profile_backup.html'
def get_success_url(self):
return reverse('profile', kwargs={'pk': self.object.pk})
def test_func(self):
obj = self.get_object()
print(obj.user == self.request.user)
return obj.user == self.request.user
Related ModelForm:
class ProfileCreateForm(forms.ModelForm):
class Meta:
model = Profile
fields = 'platform', 'content_niche', 'youtube_channel_id', 'description','profile_img', 'v_id_0', 'v_id_0_title', 'v_id_0_desc', \
'v_id_1', 'v_id_1_title', 'v_id_1_desc', 'v_id_2', 'v_id_2_title', 'v_id_2_desc'
Is it because the custom render method is not validating the form data? If so, how would I do that with an updateview?

How do i add <input type="button"> as a formfield in django

I want to have an input field as a button in my template. Just like this.I am manually rendering form fields in my template.So, how do i create a field like that in my form.
Formfield in forms.py
class DetailForm(forms.Form):
owner=forms.CharField(widget=forms.TextInput(attrs={'class':'form-control'}))
views.py
def getDetail(request):
form=DetailForm()
return render(request,'materials/addpage.html',{'form':form})
and template,
<div class="form-group">
{{form.owner}}
</div>
A minimal example of using buttons as input in Django looks like this:
Template:
<form method="POST">
{% csrf_token %}
<input type="submit" name="btn" value="yes">
<input type="submit" name="btn" value="no">
</form>
{{ val }}
Form:
class Fooform(forms.Form):
btn = forms.CharField()
View:
def test_view(request):
if request.method == 'POST':
form = Fooform(request.POST)
if form.is_valid():
val = form.cleaned_data.get("btn")
else:
form = Fooform()
return render(request, 'template.html', locals())
Libraries like crispy-forms have button widgets.

Django two forms interconnected in single template

I have another model which is like below
class Status(models.Model):
name = models.ForeignKey(User, on_delete=models.CASCADE)
status = models.BooleanField(default=False)
I just want to create a form which will render all users from django User model with upper model connected. When click single Status button it will just save that field. I'm using CreateView. How to do that?
<form method="post" action="">
User1 <input type="checkbox" name="status" />
<input type="submit" name="submit" value="Status"/>
</form>
<form method="post" action="">
User2 <input type="checkbox" name="status" />
<input type="submit" name="submit" value="Status"/>
</form>
<form method="post" action="">
User3 <input type="checkbox" name="status" />
<input type="submit" name="submit" value="Status"/>
</form>
You could use Formsets from Django. Through this way, you can set 2 forms in one, get fields from both forms and save them with a single button.
For example, you have two models bounded by a ForeignKey in your models.py file :
class MyModelA(models.Model):
field1 = ...
field2 = ...
class MyModelB(models.Model):
field1 = ...
field2 = models.ForeignKey(MyModelA, ...)
Then, in your forms.py file, you have to bound these both forms thanks to formsets :
from django.forms.models import inlineformset_factory
from .models import MyModelA, MyModelB
MyFormSet = inlineformset_factory(MyModelA, MyModelB, form=MyModelBForm, extra=1, max_num=1)
With this line, your models will be set into the same django form in your template.
Now, in your views.py file, you have to call your formset :
class MyClassCreateView(CreateView):
model = MyModelA
template_name = 'path/to/your/template'
def get_context_data(self, **kwargs):
context = super(MyClassCreateView, self).get_context_data(**kwargs)
context['my_form'] = MyFormSet(self.request.POST or None)
return context
def form_valid(self, form):
context = self.get_context_data()
document = context['my_form']
if document.is_valid():
self.object = form.save()
document.instance = self.object
document.save()
return super(MyClassCreateView, self).form_valid(form)
And finally, in your template.html file, you can call your formset :
<form method="post" action="" novalidate>
{% csrf_token %}
{{ form }}
{{ my_form }}
<input type="submit" class="btn btn-default" value="{% trans 'Save' %}" />
</form>
Hopfully it could help you to set your Django formsets

insert data into tables from form django

I want to insert data from form into database. Following are the models:
from django.db import models
from django.forms import ModelForm
# Create your models here.
class Recipe(models.Model):
title=models.CharField(max_length=200)
class User(models.Model):
fname=models.CharField(max_length=30)
lname=models.CharField(max_length=30)
class Recipe2User(models.Model):
user_id=models.ForeignKey(User)
recipe_id=models.ForeignKey(Recipe)
class Ingredient(models.Model):
recipe_id=models.ForeignKey(Recipe)
name=models.CharField(max_length=200)
class Prepration_step(models.Model):
recipe_id=models.ForeignKey(Recipe)
step=models.CharField(max_length=1000)
class RecipeForm(ModelForm):
class Meta:
model=Recipe
fields=['title']
I have created a form which takes recipe name, ingredients and preparation steps.
Below is the view which handles the post:
def createRecipe_form(request):
c = {}
c.update(csrf(request))
return render_to_response('create.html',c)
def create_recipe(request):
if request.method == 'POST':
form=RecipeForm(request.POST)
if form.is_valid():
title=form.cleaned_data['recipe_name']
r=Recipe(title)
r.save()
return HttpResponseRedirect('display.html')
else:
form=RecipeForm()
return render(request, 'create.html', {
'form': form,
})
and this is the html form I have created
<html>
<head>
<title>Create-Recipe</title>
</head>
<body>
<h1>My Recipe-Create a recipe</h1>
<form action="/recipe/submit-recipe/" method="post">
{% csrf_token %}
{% if errors %}
<div id="errors">
<ul>
{% for error in errors %}
<li>{{ error }}</li>
{% endfor %}
</ul>
</div>
{% endif %}
Title:
<input type="text" name="recipe_name" placeholder="Ex:Gobi Masala"><br>
Ingredient:
<textarea rows="4" name="recipe_ingredient" cols="50" placeholder="Ex: 2 cups rice,1/2 teaspoon oil"></textarea><br>
Preparation:
<textarea rows="4" name="recipe_preparation" cols="50" placeholder="Ex:Pour oil in frying pan,Fry onions till they turn light brown"></textarea><br>
<input type="submit" value="OK">
</form>
Please tell me how to go about inserting recipe title, ingredients and steps in Recipe, Ingredient and Prepration_step table as I am newbie to django.
Thanks
forms.py
class RecipeForm(ModelForm):
class Meta:
model = Recipe
views.py
def create_recipe(request):
if request.method == 'POST':
form=RecipeForm(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect(reverse('app_name:url_name'))
return render(request, 'create.html', {
'form': RecipeForm(),
})
html
<form action="/recipe/submit-recipe/" method="post">
{% csrf_token %}
{{form.as_p}}
<input type="submit" value="OK">
</form>

Django CSRF verification failed. Request aborted

I have a model:
class Tour(models.Model):
owner_id = models.ForeignKey(User)
name = models.CharField(max_length=50)
location = models.ManyToManyField(Location)
subscribers = models.ManyToManyField(User, related_name="sub")
tour_date = models.DateField(null=True)
description = models.CharField(max_length=300, null=True)
And a template that includes this form:
<form method="post" action="/mytours/">
{% csrf_token %}
<input name="name" value="{{ name }}" class="pull-left" type="text" placeholder="Type the tour name... "></br>
<input name="tour_date" value="{{ tour_date }}" type="text" id="datepicker" placeholder="Pick a tour date..."/>
<button class="btn" data-dismiss="modal" aria-hidden="true">Cancel</button>
<button type="submit" class="btn btn-primary">Save</button>
</form>
And in my views I am trying to add to my database what is filled in the form:
if request.method == 'POST':
location = Location.objects.get(id=1)
name = request.POST.get('name', '')
tour_date = request.POST.get('tour_date', '')
tour = Tour()
tour.owner_id = user.pk
tour.name = name
tour.tour_date = tour_date
tour.location = location
tour.save()
c = {'name':name, 'tour_date':tour_date, 'tour':tour}
c.update(csrf(request))
return render_to_response("myTours.html", c)
I am new in django and I don't know where is the problem.
You're misunderstanding what to do with the CSRF token. You're creating it on POST, but the point is to create it for the original display of the form on the GET request. It is checked by the middleware on POST, so you don't need to add it there.
You should use the render call as recommended by surfeurX, but on the call that displays the form in the first place.
What I do when I implement forms in django is writing a form class and creating an instance of it in the view. Then pass the instance to the template.
# form class eg. in models.py
from django import forms
class TourForm(forms.Form):
name = forms.CharField(max_length=50)
# in the view
if request.method == 'POST':
form = TourForm(request.POST)
if form.is_valid():
# do your stuff here with form data
else:
form = TourForm() # An unbound form
return render(request, 'myTours.html', {
'form': form,
})
in your template you can display the generated form like this:
<form action="/mytours/" method="post">{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Save" class="btn btn-primary" />
</form>
for further information just look inside the official django forms documentation
You probably need to add django.middleware.csrf.CsrfViewMiddleware to MIDDLEWARE_CLASSES and add a RequestContext to your response:
return render_to_response("myTours.html", c, context_instance=RequestContext(request))
https://docs.djangoproject.com/en/1.3/ref/contrib/csrf/
How do you render your template ??? I think your csrf_token doesn't print any hidden input, add "request" in your template context like:
return render(request, "template.html", {"var": var})
https://docs.djangoproject.com/en/dev/topics/http/shortcuts/#render