2nd Django form not rendering in HTML - django

I can not figure out what is happening here. I have two forms but the second one will not render any input fields to the template. The second form is in a different template than the first. I am still very new to programming but I have searched everywhere for an answer to this with no luck.
forms.py
from django import forms
class ContactForm(forms.Form):
contact_name = forms.CharField(required=True, widget=forms.TextInput(attrs={'placeholder': 'Your Name*'}))
contact_email = forms.EmailField(required=True, widget=forms.TextInput(attrs={'placeholder': 'Your Email*'}))
contact_phone = forms.CharField(required=True, widget=forms.TextInput(attrs={'placeholder': 'Your Phone Number*'}))
content = forms.CharField(
required=True,
widget=forms.Textarea(attrs={'placeholder': 'Your comments'})
)
def __init__(self, *args, **kwargs):
super(ContactForm, self).__init__(*args, **kwargs)
self.fields['contact_name'].label = ""
self.fields['contact_email'].label = ""
self.fields['contact_phone'].label = ""
self.fields['content'].label = ""
class EstimateForm(forms.Form):
contact_name = forms.CharField(required=True, widget=forms.TextInput(attrs={'placeholder': 'Your Name*'}))
contact_email = forms.EmailField(required=True, widget=forms.TextInput(attrs={'placeholder': 'Your Email*'}))
contact_phone = forms.CharField(required=True, widget=forms.TextInput(attrs={'placeholder': 'Your Phone Number*'}))
def __init__(self, *args, **kwargs):
super(EstimateForm, self).__init__(*args, **kwargs)
self.fields['contact_name'].label = ""
self.fields['contact_email'].label = ""
self.fields['contact_phone'].label = ""
views.py
def contact(request):
form_class = ContactForm
if request.method == 'POST':
form = form_class(data=request.POST)
if form.is_valid():
messages.success(request, 'Profile details updated.')
contact_name = request.POST.get(
'contact_name'
, '')
contact_email = request.POST.get(
'contact_email'
, '')
contact_phone = request.POST.get(
'contact_phone'
, '')
form_content = request.POST.get('content', '')
# Email the profile with the
# contact information
template = get_template('contact_template.txt')
context = Context({
'contact_name': contact_name,
'contact_email': contact_email,
'contact_phone': contact_phone,
'form_content': form_content,
})
content = template.render(context)
send_mail('Email from your website', content, context['contact_email'],
['email#gmail.com'],
fail_silently=False)
return redirect('/contact')
return render(request, 'main/contact.html', {
'form': form_class,
})
def estimate(request):
form_class = EstimateForm
if request.method == 'POST':
form = form_class(data=request.POST)
if form.is_valid():
contact_name = request.POST.get(
'contact_name'
, '')
contact_email = request.POST.get(
'contact_email'
, '')
contact_phone = request.POST.get(
'contact_phone'
, '')
# Email the profile with the
# contact information
template = get_template('estimate_template.txt')
context = Context({
'contact_name': contact_name,
'contact_email': contact_email,
'contact_phone': contact_phone,
})
content = template.render(context)
send_mail('Email from your website', content, context['contact_email'],
['email#gmail.com'],
fail_silently=False)
return redirect('main/index-v3.html')
return render(request, 'main/index-v3.html', {
'e_form': form_class,
})
template
<form role="form" action="" method="post" class="contact-form">
{% csrf_token %}
{{ e_form.as_p }}
<button type="submit" class="thm-btn">Submit</button>
</form>
This is what gets rendered in the page
<form role="form" action="" method="post" class="contact-form" style="margin-top: 25px" novalidate="novalidate">
<input type="hidden" name="csrfmiddlewaretoken" value="fsdSFKSDJDKFsdkfjJFKD">
<button type="submit" class="thm-btn">Submit</button>
</form>

You need to pass instance of form class instead of form class to template.
So change your code
return render(request, 'main/index-v3.html', {
'e_form': form_class(),
})

Related

DJANGO: forms dont show error to user (def post + ListView)

can you help me?
I can't fix problem: my don't show error validation
when I write not unique slug at form -> no error at form
I think problem at use def post() or return redirect after validations form.
I try many different solutions but nothing helps.
Maybe you should use a non-standard way to report an error?
models.py
class ShortUrl(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name='Автор URL', null=True)
url = models.CharField('Ссылка', max_length=200)
slug = models.SlugField('Короткое имя ссылки', unique=True, max_length=20)
def __str__(self):
#return self.slug
return f"Короткая ссылка: {self.user} >> {self.slug}"
​
class Meta:
verbose_name = 'Ссылка'
verbose_name_plural = 'Ссылки
forms.py
class ShortURLForm(forms.ModelForm):
slug = forms.SlugField(
label='Название URL',
required=True,
widget=forms.TextInput(attrs={'placeholder': 'Укажите уникальный URL'})
)
url = forms.CharField(
label='Ссылка',
required=True,
widget=forms.TextInput(attrs={'placeholder': 'Ссылка которую нужно сократить'})​
)
class Meta:
model = ShortUrl
fields = ['user', 'url', 'slug']
widgets = {'user': forms.HiddenInput()}
views.py
class ShortURLPage(LoginRequiredMixin, ListView):
model = ShortUrl
template_name = 'main/shorts.html'
context_object_name = 'shorts'
​
def get_context_data(self, *, object_list=None, **kwargs):
ctx = super(ShortURLPage, self).get_context_data(**kwargs)
ctx['form'] = ShortURLForm()
userurls = ShortUrl.objects.filter(user=self.request.user)
ctx['shorts'] = userurls
ctx['title'] = 'Добавление ссылок'
return ctx
​
def post(self, request, *args, **kwargs):
post = request.POST.copy()
post['user'] = request.user
request.POST = post
form = ShortURLForm(request.POST)
​
if form.is_valid():
slug = form.cleaned_data['slug']
url = form.cleaned_data['url']
form.save()
​
return redirect('shorts')
shorts.html
<form method="post" class="form">
{% csrf_token %}
{{ form }}
<button class="button" type="submit">Создать ссылку</button>
</form>
urls.py
urlpatterns = [
path('', views.homepage, name='home'),
path('about/', views.about, name='about'),
path('shorts/', views.ShortURLPage.as_view(), name='shorts'),
path('shorts/<str:slug>/', views.urlRedirect, name='redirect'),
]
Ok, you're not so far away with accomplishing what you want.
Generally your post method should look like this:
def post(self, request, *args, **kwargs):
post = request.POST.copy()
post['user'] = request.user
request.POST = post
form = ShortURLForm(request.POST)
​
if form.is_valid():
slug = form.cleaned_data['slug']
url = form.cleaned_data['url']
form.save()
else:
context = {
'form': form,
}
return render(
request,
self.template_name,
context,
)
return redirect('shorts')
Then, you should write your shorts.html template like this:
<form method="post" class="form">
{% csrf_token %}
{{ form.non_field_errors }}
{{ form.errors }}
{{ form }}
<button class="button" type="submit">Создать ссылку</button>
</form>

Issue with django request,get user from bd

SO,I want to get user details from database and show them in user.html,but I cant do it. They dont display in this file. I tried to do class UserView(ListView):, but it wasnt working. Maybe I didnt understand request.
view.py
def registerform(request): ##registerform
form = SightUp(request.POST or None)
if form.is_valid():
user_obj = form.save()#Сохранение значений в датабазе методом .save()
username = form.cleaned_data.get('username')
raw_password = form.cleaned_data.get('password1')
email = form.cleaned_data.get('email')
user = authenticate(username=username,password =raw_password,email=email)
login(request,user)
return redirect('/userprofile/')# ЗАМЕНИТЬ
context = {'form':form }
return render(request,'user.html',context)
#def userprofiles(request):
# userall = detailsuser.objects.all()
# context = {
# 'objects':userall
# }
# return render(request,'userprofile.html', context)
class UserView(ListView):
model = User
template_name = 'userprofile.html'
context = 'detailsuser'
def get_queryset(self):
return detailsuser.objects.filter(user = self.request.user)
forms.py
class SightUp(UserCreationForm):
first_name = forms.CharField( widget = forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'First Name'}), max_length=32, help_text='First name')
last_name = forms.CharField( widget = forms.TextInput(attrs={'class':'form-control','placeholder':'Last name'}), max_length=32)
email = forms.EmailField(widget =forms.TextInput(attrs={'class':'form-control', 'placeholder': 'Email'}), max_length =64,help_text='Enter valid Email')
username = forms.CharField(widget =forms.TextInput(attrs={'class':'form-control','placeholder':'Username'}))
password1 = forms.CharField(widget =forms.PasswordInput(attrs={'class':'form-control','placeholder':'Password1'}))
password2 = forms.CharField(widget =forms.PasswordInput(attrs={'class':'form-control','placeholder':'Password2'}))
class Meta(UserCreationForm.Meta):
model = User
fields = UserCreationForm.Meta.fields + ('first_name','last_name','email')
user.html
{% for i in detailsuser %}
<h1> yourname: i.email </h1>
{% endfor %}
<h1>Your last name:</h1>
<h1>Your nickname:</h1>
models.py
class detailsuser(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
Your challenge stems from the register view you need to make a conditional test for the POST method like so:
def registerform(request): ##registerform
if request.method == 'POST': #Here is where you make the condition for POST
form = SightUp(request.POST or None)
if form.is_valid():
user_obj = form.save()#Сохранение значений в датабазе методом .save()
username = form.cleaned_data.get('username')
raw_password = form.cleaned_data.get('password1')
email = form.cleaned_data.get('email')
user = authenticate(username=username,password =raw_password,email=email)
login(request,user)
return redirect('/userprofile/')# ЗАМЕНИТЬ
else:
form = SightUp()
context = {'form':form }
return render(request,'user.html',context)
Your user html had a problem, you didn't add the {% endfor %} tag that's why you are not seeing any information. Do something like so:
{% for i in detailsuser %}
<h1> yourname: i.email </h1>
{% endfor %}
<h1>Your last name:</h1>
<h1>Your nickname:</h1>
{% endfor %}
I ansewer it. Problem was because of cycle in my template

ModelForm doesn´t validate

I just cant make my modelform to validate. I call it from view, and GET prints it right, but when POST occurs it doesn´t validate.
Allways getting
ValueError Exception Value: The view
gestionPartesMedicos.views.partes_medicos_add didn't return an
HttpResponse object. It returned None instead.
form´s name attributes correspond to model´s and form´s.
---UPDATED---
This my model:
class MedicalList(models.Model):
worker= models.ForeignKey(worker, on_delete=models.CASCADE)
description=models.CharField(max_length=255)
upload=models.FileField(upload_to=user_directory_path, null=False, blank=False)
created_at=models.DateTimeField(auto_now_add=True)
this my form class:
class MedicalListForm(forms.ModelForm):
worker = forms.ModelChoiceField(
queryset=Worker.objects.none(),
empty_label=None,
widget=forms.Select(attrs={'class': 'form-control'})
)
description=forms.CharField(
widget=forms.Textarea(attrs={'class': 'form-control'})
)
upload=forms.FileField(
widget=forms.ClearableFileInput(attrs={'class': 'form-control'})
)
class Meta:
model = MedicalList
fields = (
'worker',
'description',
'upload',
)
def __init__(self, *args, **kwargs):
user_id = kwargs.pop('user_id', None)
super().__init__(*args, **kwargs)
self.fields['worker'].queryset = Worker.objects.filter(user_id=user_id)
And this my view in trouble:
def medical_list_add(request):
if request.method == "POST":
form = MedicalListForm(request.POST,request.FILES,user_id=request.user)
if form.is_valid():
form.save()
return redirect('medical_list')
else:
form = MedicalListForm(user_id=request.user)
return render(request, 'medical_list_add.html', {'form': form})
The form in template:
<form method="POST">
{% csrf_token %}
<div class="form-group">
{{ form.as_p }}
<button type="submit" class="btn btn-primary">Guardar</button>
<a class="nav-item linking" href = "{% url 'medical_list' %}">Cancel</a>
</div>
</form>
this is the response I get:
Request information USER 12345
GET No GET data
POST Variable Value csrfmiddlewaretoken
'2zG3amQlZlPsrytMtF91ZiJQDZ679E2Zgrx3YxcOPzcNj6dNCl101Lj0UV96STLY'
worker '14' description 'pm' upload 'medical.pdf'
Might it be around Model field created_at? just trying to guess, totally lost.
thanks in advance
The main problem is that your view does not return a HTTP response in case the form was invalid. You should unindent the render(…) call with:
def medical_list_add(request):
if request.method == "POST":
form = MedicalListForm(request.POST,request.FILES,user_id=request.user)
if form.is_valid():
form.save()
return redirect('medical_list')
else:
form = MedicalListForm(user_id=request.user)
# &downarrow;&downarrow; both for GET and a failed POST
return render(request, 'medical_list_add.html', {'form': form})
Furthermore the form fields are specified at class level. By constructing a form field in the __init__ method, this will not use that
class MedicalListForm(forms.ModelForm):
worker = forms.ModelChoiceField(
queryset=Trabajador.objects.none(),
empty_label=None,
widget=forms.Select(attrs={'class': 'form-control'})
)
description=forms.CharField(
widget=forms.Textarea(attrs={'class': 'form-control'})
)
upload=forms.FileField(
widget=forms.ClearableFileInput(attrs={'class': 'form-control'})
)
class Meta:
model = MedicalList
fields = (
'worker',
'description',
'upload',
)
def __init__(self, *args, **kwargs):
user_id = kwargs.pop('user_id', None)
super().__init__(*args, **kwargs)
self.fields['worker'].queryset = worker.objects.filter(user_id=user_id)
If your form handles files, you should set the enctype=… parameter to multipart/form-data:
<form method="POST" enctype="multipart/form-data">
…
</form>

Django EmailMessage send() works and then gives HTTP Error 400: Bad Request

I have two forms on my clients site; one on the homepage and one on the contact page. I will test the forms one minute and they work fine and then I'll test again at later and I get HTTP Error 400: Bad Request - its driving me nuts because I can't figure it out. I disable one of the forms to troubleshoot, but that did nothing. Below are my forms; please tell me I am missing something obvious :)
Form Template
<form action="" role="form" method="post" id="contactForm">
{% csrf_token %}
{{ form.as_p }}
<div class="form-group">
<button class="btn btn-color-out btn-block" type="submit">Send Message</button>
</div>
</form>
Contact View
def contact(request):
form_class = ContactForm
if request.method == 'POST':
form = form_class(data=request.POST)
messages.add_message(request, messages.SUCCESS, 'Thank you, your message was received.')
if form.is_valid():
fullname = request.POST.get('fullname', '')
phone_number = request.POST.get('phone_number', '')
email_address = request.POST.get('email_address', '')
message_content = request.POST.get('message_content', '')
subject = 'Contact Information Submitted from Trust and Beneficiary Advocates'
from_email = settings.DEFAULT_FROM_EMAIL
recipient_list = ['kfritz#*****.com', 'charles#*****.com']
ctx = {
'title': 'Contact Us',
'subject1': subject,
'fullname': fullname,
'phone_number': phone_number,
'email_address': email_address,
'message_content': message_content
}
message = get_template('email_forms/contact_form_email.html').render(Context(ctx))
msg = EmailMessage(subject, message, from_email=from_email, to=[email_address], bcc=recipient_list)
msg.content_subtype = 'html'
msg.send()
return redirect('/thank-you/')
return render(request, 'pages/contact.html', {
'form': form_class, 'title': 'Contact Us'
})
Index(Home) View
def index(request):
form_class = FooterForm
if request.method == 'POST':
form = form_class(data=request.POST)
if form.is_valid():
fullname = request.POST.get('fullname', '')
phone_number = request.POST.get('phone_number', '')
email_address = request.POST.get('email_address', '')
message_content = request.POST.get('message_content', '')
subject = 'Contact Information Submitted from Trust and Beneficiary Advocates'
from_email = settings.DEFAULT_FROM_EMAIL
recipient_list = ['kfritz#***.com', 'charles#***.com']
ctx = {
'title': 'Trust and Beneficiary Advocates',
'subject': subject,
'fullname': fullname,
'phone_number': phone_number,
'email_address': email_address,
'message_content': message_content
}
message = get_template('email_forms/contact_form_email.html').render(Context(ctx))
msg = EmailMessage(subject, message, from_email=from_email, to=[email_address], bcc=recipient_list)
msg.content_subtype = 'html'
msg.send()
return redirect('/thank-you/')
return render(request, 'pages/index.html', {
'form': form_class, 'title': 'Trust and Beneficiary Advocates'
})
Thank you.
You should use msg.send(fail_silently = True) to send emails without failing to send mail to a bogus or invalid email id.
For both views with email sending functionality,use it like this :
message = get_template('...../email_template.html').render(Context(ctx))
msg = EmailMessage(subject, message, from_email=from_email, to=[email_address], bcc=recipient_list)
msg.content_subtype = 'html'
msg.send(fail_silently = True)

Form preview Django

I'm trying to use django's FormPreview but can't get it to work properly. Here's my code:
models.py
class jobpost(models.Model):
CONTENT_CHANNELS = (
('Full Time','Full Time'),
('Part Time','Part Time'),
('Contract','Contract'),
)
user = models.ForeignKey(User)
job_id = models.AutoField(primary_key=True)
#user = models.ForeignKey(User, editable = False)
job_type = models.CharField(max_length=255,null=True, choices=CONTENT_CHANNELS,default='Full Time')
job_location = models.CharField(max_length=255,null=True)
job_title = models.CharField(max_length=255,null=True)
job_description = models.TextField(null=True)
def __unicode__(self):
#return self.user
return self.job_location
return self.job_type
return self.job_title
return self.job_description
admin.site.register(jobpost)
class jobpostForm(ModelForm):
class Meta:
model = jobpost
fields = ('user','job_type','job_location','job_title','job_description')
widgets = {
'job_type':RadioSelect(),
'job_location':TextInput(attrs={'size':'70'}),
'job_description':Textarea(attrs={'cols':200, 'rows':10}),
}
def __init__(self, *args, **kwargs):
self.helper = FormHelper()
self.helper.form_class = 'horizontal-form'
self.helper.form_id = 'id-jobpostform'
self.helper.form_class = 'blueForms'
self.helper.form_method = 'post'
#self.helper.form_action = '/'
self.helper.add_input(Submit('submit_addcontent', 'Submit'))
super(jobpostForm, self).__init__(*args, **kwargs)
views.py
def main_page(request):
"""
If users are authenticated, direct them to the main page. Otherwise, take
them to the login page.
"""
if request.method == 'POST':
form = jobpostForm(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect('/thanks/')
else:
form = jobpostForm()
c = {}
c.update(csrf(request))
return render_to_response('portal/job_post.html',{'form':form},context_instance=RequestContext(request))
preview.py
class SomeModelFormPreview(FormPreview):
form_template = 'portal/job_post.html'
preview_template = 'portal/preview.html'
def done(self, request, cleaned_data):
f = self.form(request.POST)
f.save()
pdb.set_trace()
print "done"
# Do something with the cleaned_data, then redirect
# to a "success" page.
return HttpResponseRedirect('/form/success')
job_post.html
<form action = "" method = "POST" enctype="multipart/form-data" class="blueForms" id="id-jobpostform">
{% csrf_token %}
{% crispy form %}
<input name="submit" type="submit" value="Post" >
urls.py
(r'^$', main_page),
(r'^post/$', SomeModelFormPreview(jobpostForm)),
When i submit the form it goes to the / home page and submits the info. I want to first prview the form and then submit..plz tell me what i am missing or doing wrong.