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
Related
I've created a custom HTML form for my model, just like I want to add a post from the front-end. I already created a page with the name add-post.html
<form method="POST" action="">
{% csrf_token %}
<input name="title" type="text">
<textarea spellcheck="false" name="description"></textarea>
<input type="file" name="image" #change="fileName" multiple />
<select required name="priority">
<option value="Low" selected>Low</option>
<option value="Medium">Medium</option>
<option value="High">High</option>
</select>
<input type="checkbox" name="on_hold">
<button type="submit">Add ToDo</button>
</form>
Here's my model.py
class Todo(models.Model):
title = models.CharField(max_length=100)
image = models.ImageField(null=True, blank=True, upload_to='todo/images/')
description = RichTextField()
Low, Medium, High = 'Low', 'Medium', 'High'
priorities = [
(Low, 'Low'),
(Medium, 'Medium'),
(High, 'High'),
]
priority = models.CharField(
max_length=50,
choices=priorities,
default=Low,
)
on_hold = models.BooleanField(default=False)
No, I want to use the above custom HTML form to post data and save it to this model database. instead of using {% form.as_p %}
And I also created a particular page to update this post from the front-end but don't know how to make it work.
Can you please guide me on how can I save data from the custom form and also update it from the custom form?
Appreciate your response :)
#Mubasher Rehman - You are almost there
forms.py
class TodoCreationForm(forms.ModelForm):
class Meta:
model = Todo
fields = ('title','image','description','priorities','priority','on_hold',)
views.py
from django.contrib.messages.views import SuccessMessageMixin
from django.views.generic import CreateView
class CreatProduct(SuccessMessageMixin,CreateView):
model = Todo
form_class = TodoCreationForm
template_name = "add_post.html"
success_message = "Todo was created successfully"
error_message = "Error saving the Todo, check fields below."
add_post.html
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
{{form.as_p}}
<button type="submit" class="btn btn-primary">Submit</button>
</form>
#Mubasher Rehman - I fought this problem myself for awhile and finally found a solution. My situation was much different than yours, but try this:
In your views.py overwrite the form_valid method like so:
def form_valid(self, form):
if self.request.POST:
if form.is_valid():
t= Todo.objects.create(title='title', image='image', description='description', priority='priority', on_hold='on_hold')
t.save()
return super(ModelView, self).form_valid(form)
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?
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.
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.
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