This is my view:
def my_view(request):
if request.method == 'GET':
form = MyForm(initial={'user': "my_user"})
if request.method == 'POST':
form = MyForm(request.POST)
if form.is_valid():
print("form is valid")
else:
form = MyForm()
return render(request, 'my_template.html', {'form': form})
And this is the form
class MyForm(forms.Form):
my_field = forms.CharField(max_length=100)
user = forms.CharField(widget=forms.HiddenInput())
def clean(self):
cleaned_data = super(MyForm, self).clean()
my_field = cleaned_data.get('my_field')
if not my_field:
raise forms.ValidationError('error')
Nothing is printed on the console (print("form is valid")), so the form is not valid, and this problem comes from the hidden field.
When I work without the hidden fields, the form is valid
What's wrong with my code ? How to initialize the values of hidden fields from the view function (or another way to do it without including it in the HTML) ?
The solution was not really related to my view or form class but to the template. So I am posting this if anyone missed it out: Don't forget to include the hidden fields in the form:
{% for hidden_field in form.hidden_fields %}
{{ hidden_field }}
{% endfor %}
Related
I am trying to upload image from form but whenever I submit everything got saved in database other than image field.But when I try to do samething from admin panel it works.
models.py
class Post(models.Model):
title = models.CharField(("Title"), max_length=100)
title_image = models.ImageField(
("Title Image"),
upload_to='static/Images/TitleImages/',
max_length=None,
blank = True,null = True)
Forms.py
class AddPostForm(ModelForm):
class Meta:
model = Post
fields = ['title','title_image']
Views.py
class AddPostView(LoginRequiredMixin,CreateView):
model = Post
template_name = 'MainSite/add_post.html'
fields = '__all__'
def dispatch(self, request, *args, **kwargs):
if request.user.is_anonymous:
messages.error(request,"You need to login to access this page")
return redirect('/')
elif request.user.is_superuser:
if request.method == "POST":
form = AddPostForm(request.POST)
if form.is_valid():
form.save()
messages.success(request,"POST added successfully")
return redirect('/')
else:
print("error")
else:
print("method is not post")
form = AddPostForm()
return render(request,'MainSite/add_post.html',{'form':form})
else :
messages.error(request,"You need to have superuser permission to access this page")
return redirect('/')
addpost.html
<form action= "" method="POST" enctype="multipart/form-data">
{% csrf_token %}
{{ form.media }}
{{ form|crispy}}
<button class="btn btn-primary profile-button" style = "width:150px;"type="submit" >Add Post</button></div>
</form>
my model have 2 things title and title_image but whenever I submit only title is saved and when I do through admin panel it works.
I dont know what I am doing wrong here any advice will be helpful.
Thanks in advance
You've to pass request.FILES in order to save files
if request.method == "POST":
form = AddPostForm(request.POST, request.FILES)
if form.is_valid():
form.save()
messages.success(request,"POST added successfully")
return redirect('/')
I'm creating a home page for my Django webapp, outside of Django admin. I'd like the home page to have a very simple ModelForm that when submitted, writes to the database.
I'm getting the following error at /home/ currently and not sure how to resolve it.
AttributeError at /home/ 'ActionCodeForm' object has no attribute
'is_bound'
I know about bound and unbound forms and have read the docs, but I am not sure how to actually implement them.
Here is my model:
class ActionCode(models.Model):
action_code = models.CharField(blank=False, max_length=10,
verbose_name="Action Code")
Here is my ModelForm:
class ActionCodeForm(ModelForm):
class Meta:
model = ActionCode
fields = ('action_code',)
def __init__(self, *args, **kwargs):
super(ActionCodeForm).__init__(*args, **kwargs)
Here is my view:
def action_code_form(request):
if request.method == 'GET':
form = ActionCodeForm()
else:
form = ActionCodeForm(request.POST)
if form.is_valid():
action_code = form.cleaned_data['action_code']
form.save()
else:
form = ActionCodeForm()
return render('action_code_form.html', {'form': form},
context_instance=RequestContext(request))
And here is my template, action_code_form.html:
<form method="post" action="">
{% csrf_token %}
<table>
{{ form }}
</table>
<input type="submit" value="Submit"/>
</form>
And urls.py:
from home.views import action_code_form
urlpatterns = [
url(r'^home/', action_code_form, name="home"),
]
You need to check if the form is valid only if the method is POST. Also, the first param of render() must be request
Your view should be as follows:
def action_code_form(request):
form = ActionCodeForm()
if request.method == 'POST':
form = ActionCodeForm(request.POST)
if form.is_valid():
action_code = form.cleaned_data['action_code']
form.save()
return render(request, 'action_code_form.html', {'form': form})
If you need to override __init__() in your model form, then you should add self as a second parameter to super() (there is no need to keep the following two lines if you do not have any specific behavior that you want to add to your form):
def __init__(self, *args, **kwargs):
super(ActionCodeForm, self).__init__(*args, **kwargs)
I have tried to use modelformset_factory(User) to create a form to add (and in next step edit) a user.
I'm confused, why it creates a form with my current user and an empty one for a new one?
Any Idea how i could remove the one with the current?
Here is my view.py code:
#login_required
def update_or_edit_user_profile(request, UserID = None, template_name='userprofile_form.html'):
#check when a userid is provided if its the personal or if the user is allowed to edit the profile
if UserID != None:
if (request.user.has_perm('change_user_profile') or request.user.pk == UserID):
pass
else:
raise PermissionDenied
# when user is allowed to continue:
UserFormSet = modelformset_factory(User)
if request.method == 'POST':
userformset = UserFormSet(request.POST, request.FILES)
if userformset.is_valid():
newUser=userformset.save()
else:
userformset = UserFormSet()
return render_to_response(template_name, {
"userformset": userformset,
})
and my template:
<form action="" method="post">{% csrf_token %}
{{ userformset.as_p }}
<input type="submit" value="Send message" />
</form>
You're confusing forms with formsets. A formset is a collection of forms, so Django is giving you exactly what you asked for. If you only want a single form, then that's what you should use:
class UserForm(forms.ModelForm):
class Meta:
model = User
def update_or_edit_user_profile...
user = User.objects.get(pk=UserID)
if request.method == 'POST':
form = UserForm(request.POST, instance=user)
if form.is_valid():
form.save()
return HttpResponseRedirect('/')
else:
form = UserForm(instance=User)
return render(request, template_name, {'form': form})
I have a form where I must enter e-mail, but in the template do not have space for input, only after passing the validation window appears with the introduction e-mail.
At this moment I see only send button.
This is my code:
<div class="col-lg-6">
<form action="./" method="post">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="send">
</form>
</div>
model.py
class InputEmail(models.Model):
email = models.EmailField()
def __unicode__(self):
return self.email
forms.py
from models import InputEmail
from django import forms
class EmailForm(forms.ModelForm):
class Meta:
model = InputEmail
fields = ('email',)
views.py
class Home(View):
template_name = 'index.html'
def get(self, request):
return render(request, self.template_name)
def post(self, request):
if request.method == 'POST':
form = EmailForm(request.POST)
if form.is_valid():
form.save()
messages.success(request, "You send e-mail to us!")
return HttpResponseRedirect('./')
else:
form = EmailForm()
return render(request, 'index.html', {
'form': form
})
The rest - writing and reading from the database works fine.
How enter the input and give it a style?
well the problem is that the first time you arrive to the view the get method is being called (and it is okay, since this is a GET request).
But, inside that get method you are not sending your form to the template. So it can't be rendered.
instead, your get method should look like that:
def get(self, request):
form = EmailForm()
return render(request, self.template_name, {"form": form})
note that the condition in the post method is redundant. You have an "else" but you never get there since the post method is only called when it is a POST request.
Meaning your post method should look like this:
def post(self, request):
form = EmailForm(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect('./')
return render(request, self.template_name, {
'form': form
})
I want to limit a queryset for a form based on the user sending the request. I am having some trouble getting a ModelForm to properly limit the queryset of a field when the form is submitted but invalid. The form gets redisplayed with the error text, but no longer has the queryset limited. What could be the cause here?
models.py
from django.db import models
from django.contrib.auth.models import User
class Patient(models.Model):
name = models.CharField(max_length=100)
doctor = models.ForeignKey(User)
def __unicode__(self):
return self.name
class Prescription(models.Model):
name = models.CharField(max_length=100)
patient = models.ForeignKey(Patient)
views.py
import medical.models as models
import medical.forms as forms
from django.shortcuts import render
def add_form(request):
if request.method == 'POST':
form = forms.PrescriptionForm(request.POST)
if form.is_valid():
form.save()
else:
form = forms.make_prescription_form(request.user)
return render(request, 'add_form.html', {'form': form})
forms.py
import medical.models as models
from django.forms import ModelForm, ModelChoiceField
class PrescriptionForm(ModelForm):
class Meta:
model = models.Prescription
def make_prescription_form(dr):
class PrescriptionForm(ModelForm):
patient = ModelChoiceField(queryset=models.Patient.objects.filter(doctor=dr))
class Meta:
model = models.Prescription
return PrescriptionForm
add_form.html
{{ request.user.first_name }}
{% if form.errors %}
<p style="color: red;">Please correct the error{{ form.errors|pluralize }} below.</p>
{% endif %}
<form action="" method="post">{% csrf_token %}
{{ form }}
<br>
<input type="submit" value="Submit">
</form>
I would greatly appreciate any help with this, or suggestion on a better way to achieve the same thing! Let me know if any more files would be helpful. I'm using Django 1.3.
First off, it looks like you left off a bit - make_prescription_form returns a class, not a form instance, and you're passing the class directly to the rendering in the GET path. I am assuming that's a typo.
You're not using your make_prescription_form wrapper in the POST path. The smallest change from this implementation would be:
def add_form(request):
form_class = forms.make_prescription_form(request.user)
if request.method == 'POST':
form = form_class(request.POST)
if form.is_valid():
form.save()
else:
form = form_class()
return render(request, 'add_form.html', {'form': form})
As for other ways to do this - you can just set the form field's queryset directly in your view.
forms.py
class PrescriptionForm(ModelForm):
class Meta:
model = models.Prescription
views.py
def add_form(request):
if request.method == 'POST':
form = PrescriptionForm(request.POST)
form.fields['patient'].queryset = models.Patient.objects.filter(doctor=request.user)
if form.is_valid():
form.save()
else:
form = PrescriptionForm()
form.fields['patient'].queryset = models.Patient.objects.filter(doctor=request.user)
return render(request, 'add_form.html', {'form': form})
Or set doctor as an argument to PrescriptionForm's __init__ and update the queryset there:
forms.py
class PrescriptionForm(ModelForm):
class Meta:
model = models.Prescription
def __init__(self, *args, doctor=None, **kwargs):
super(PrescriptionForm, self).__init__(*args, **kwargs)
if self.doctor is not None:
self.fields['patient'] = models.Patient.objects.filter(doctor=doctor)
views.py
def add_form(request):
if request.method == 'POST':
form = PrescriptionForm(request.POST, doctor=request.user)
if form.is_valid():
form.save()
else:
form = PrescriptionForm(doctor=request.user)
return render(request, 'add_form.html', {'form': form})