:Django forms - input boxes not rendering in template - python

I can't get my form to show up on my rendered template. The submit button is there but nothing else. I have two forms, one works fine its the EstimateForm I can't get to show.
Edit: I forgot to mention the estimate form is part of the base template, in particular it's in the website footer. The contact template is extending the base template. The form in the base template is not showing up on any templates. Sorry for not putting this information on at first.
This is the template
<form role="form" action="" method="post" class="contact-form" style="margin-top: 25px">
{% csrf_token %}
{{ estimate_form.as_p }}
<button type="submit" class="thm-btn">Submit</button>
</form>
This is what gets rendered
<form role="form" action="" method="post" class="contact-form" style="margin-top: 25px" novalidate="novalidate">
<input type="hidden" name="csrfmiddlewaretoken" value="lfudMn6U8TBJ2czhZM4UZTINnP6xoLZs">
<button type="submit" class="thm-btn">Submit</button>
</form>
Forms. py
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'})
)
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(BottomForm, 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():
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'],
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'
, '')
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'],
['#gmail.com'],
fail_silently=False)
return redirect('/contact')
return render(request, 'main/contact.html', {
'estimate': form_class,
})

You are passing the form with key 'estimate'
return render(request, 'main/contact.html', {
'estimate': form_class,
})
But in template you are trying to access it by
{{ estimate_form.as_p }}
Just correct it to {{ estimate.as_p }}

in the view you define just ContactForm as form_class. But you doesn't define estimate_form, that is why you doesn't see it.
so your view have to look like this:
def contact(request):
form_class = ContactForm
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'
, '')
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'],
fail_silently=False)
return redirect('/contact')
return render(request, 'main/contact.html', {
'form': form_class, 'estimate_form': estimate_form
})

You have at least four problems here, although not all of them are related to the issue you are asking about.
Firstly is that you pass the form class, rather than an instance, to the template. You need to instantiate the class first.
Secondly, you pass that into the template under the name estimate, but in the template you refer to it as estimate_form. You need to use the same name.
Thirdly, when the form is not valid, you don't pass the instantiated form with the errors back to the template, so the user will never know why it is not valid.
Fourth, when the form is valid you should get the data from form.cleaned_data, not directly from the POST.
Putting it all together:
def estimate(request):
form_class = EstimateForm
if request.method == 'POST':
form = form_class(data=request.POST)
if form.is_valid():
contact_name = form.cleaned_data['contact_name']
contact_email = form.cleaned_data['contact_email']
contact_phone = form.cleaned_data['contact_phone']
form_content = form.cleaned_data['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'],
['binford.blake#gmail.com'],
fail_silently=False)
return redirect('/contact')
else:
form = form_class()
return render(request, 'main/contact.html', {
'estimate_form': form,
})

Related

Django - 'This field is required on form' load

I have a Django view that shows two create forms.
Whenever the page loads all of the input fields display - 'This field is required".
enter image description here
Template code
{% block content %}
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ listing_create_form.as_p }}
{{ listing_media_form.as_p }}
<button type="submit">Submit Form</button>
</form>
{% endblock %}
views.py
#login_required
def createListing(request):
listing_create_form = ListingCreateForm(request.POST or None, request.FILES)
listing_media_form = ListingMediaForm(request.POST or None, request.FILES)
if request.method == 'POST':
if listing_create_form.is_valid() and listing_media_form.is_valid():
listing_create_form.instance.created_by = request.user
form = listing_create_form.save()
form.save()
new_listing_id = form.pk
# loop over images to upload multiple
for image_uploaded in request.FILES.getlist('image'):
image_instance = ListingMedia.objects.create(listing=form, image=image_uploaded)
image_instance.save()
return redirect('boat_listings')
context = {'listing_create_form': listing_create_form, 'listing_media_form': listing_media_form}
return render(request, 'listings/listing_create_form.html', context)
forms.py
class ListingCreateForm(forms.ModelForm):
class Meta:
model = Listings
widgets = {
"featured_image": forms.FileInput(
attrs={
"enctype": "multipart/form-data"
}
),
}
fields = "__all__"
exclude = ("created_by", "created_on", "last_modified",)
class ListingMediaForm(forms.ModelForm):
class Meta:
# image = forms.FileField(widget=forms.ClearableFileInput(attrs={'multiple': True}))
widgets = {
"image": forms.ClearableFileInput(
attrs={
"multiple": True
}
),
}
model = ListingMedia
fields = ['image']
Django template should render without field required message before user has inputted invalid inputs.
it looks like when you initialise form instances, it gets data and tries to validate so that's what you are receiving error messages.
change your view:
#login_required
def createListing(request):
if request.method == 'POST':
listing_create_form = ListingCreateForm(request.POST, request.FILES)
listing_media_form = ListingMediaForm(request.POST, request.FILES)
if listing_create_form.is_valid() and listing_media_form.is_valid():
listing_create_form.instance.created_by = request.user
form = listing_create_form.save()
form.save()
new_listing_id = form.pk
# loop over images to upload multiple
for image_uploaded in request.FILES.getlist('image'):
image_instance = ListingMedia.objects.create(listing=form, image=image_uploaded)
image_instance.save()
return redirect('boat_listings')
else:
listing_create_form = ListingCreateForm()
listing_media_form = ListingMediaForm()
context = {'listing_create_form': listing_create_form, 'listing_media_form': listing_media_form}
return render(request, 'listings/listing_create_form.html', context)

Django form post doesn't save to DB

The form I made on Django doesn't save any data, I think it's a validation issue but I can't find where the problem is - whenever I click on the "submit" button the page is refreshed but no new entries are created - when I do that from Django Admin it works fine.
I'm a complete beginner and this is my very first Django project.
models.py
class Utente(models.Model):
id_utente = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=True)
gen_utente = models.CharField(max_length=7, choices=GEN_CHOICES)
age_utente = models.CharField(max_length=2)
con_utente = CountryField()
per_utente = models.CharField(max_length=18, choices=PER_CHOICES)
pres_utente = models.CharField(max_length=11, choices=PRES_CHOICES)
doc_utente = models.CharField(max_length=29, choices=DOC_CHOICES)
vis_utente = models.CharField(max_length=10, choices=VIS_CHOICES)
san_utente = models.CharField(max_length=17, choices=SAN_CHOICES)
nnb_utente = models.CharField(max_length=5, choices=NNB_CHOICES)
unnb_utente = models.CharField(max_length=8, choices=UNNB_CHOICES)
va_utente = models.CharField(max_length=12, choices=VA_CHOICES)
tem_utente = models.DateField()
res_utente = models.CharField(max_length=5000)
def __str__(self):
return f'Utente n: {self.id_utente} del {self.tem_utente}'
forms.py (I've removed the labels)
class UtenteForm(forms.ModelForm):
class Meta:
model = Utente
fields = ['id_utente', 'gen_utente', 'age_utente', 'con_utente', 'per_utente', 'pres_utente', 'doc_utente', 'vis_utente', 'san_utente', 'nnb_utente', 'unnb_utente', 'vac_utente', 'tem_utente', 'res_utente']
labels = {
'id_utente': '.......',
'gen_utente': '.......',
'age_utente': '.......',
'con_utente': '.......',
'per_utente': '.......',
'pres_utente': '.......',
'doc_utente': '.......',
'vis_utente': '.......',
'san_utente': '.......',
'nnb_utente': '.......',
'unnb_utente': '.......',
'vac_utente': '.......',
'tem_utente': '.......',
'res_utente': '.......'
}
widgets = {
'id_utente': forms.TextInput(attrs={'class': 'form-control', 'disabled': True}),
'gen_utente': forms.Select(choices=SESSO_CHOICES, attrs={'class': 'form-control'}),
'age_utente': forms.TextInput(attrs={'class': 'form-control', 'pattern': '([0-9]{2})'}),
'con_utente': CountrySelectWidget(attrs={'class': 'form-control'}),
'per_utente': forms.Select(choices=PERMANENZA_CHOICES, attrs={'class': 'form-control'}),
'pres_utente': forms.Select(choices=PRESENZA_CHOICES, attrs={'class': 'form-control'}),
'doc_utente': forms.Select(choices=DOCUMENTI_CHOICES, attrs={'class': 'form-control'}),
'vis_utente': forms.Select(choices=VISITEPREG_CHOICES, attrs={'class': 'form-control'}),
'san_utente': forms.Select(choices=DOCSANITARI_CHOICES, attrs={'class': 'form-control'}),
'nnb_utente': forms.Select(choices=MMG_CHOICES, attrs={'class': 'form-control'}),
'unnb_utente': forms.Select(choices=USOMMG_CHOICES, attrs={'class': 'form-control'}),
'vac_utente': forms.Select(choices=VACCINOCOVID_CHOICES, attrs={'class': 'form-control'}),
'vis_utente': forms.DateInput(attrs={'class': 'form-control', 'type': 'date'}),
'res_utente': forms.Textarea(attrs={'class': 'form-control', 'rows':'3'})
}
views.py
# Add new utente
def aggiungi_utente(request):
if request.method == 'POST':
form = UtenteForm(request.POST)
if form.is_valid():
new_id_utente = form.cleaned_data ['id_utente']
new_gen_utente = form.cleaned_data ['gen_utente']
new_age_utente = form.cleaned_data ['age_utente']
new_con_utente = form.cleaned_data ['con_utente']
new_per_utente = form.cleaned_data ['per_utente']
new_pres_utente = form.cleaned_data ['pres_utente']
new_doc_utente = form.cleaned_data ['doc_utente']
new_vis_utente = form.cleaned_data ['vis_utente']
new_san_utente = form.cleaned_data ['san_utente']
new_nnb_utente = form.cleaned_data ['nnb_utente']
new_usnnb_utente = form.cleaned_data ['unnb_utente']
new_vac_utente = form.cleaned_data ['vac_utente']
new_tem_utente = form.cleaned_data ['tem_utente']
new_res_utente = form.cleaned_data ['res_utente']
new_utente = Utente(
id_utente = new_id_utente,
gen_utente = new_gen_utente,
age_utente = new_age_utente,
con_utente = new_con_utente,
per_utente = new_per_utente,
pres_utente = new_pres_utente,
doc_utente = new_doc_utente,
vis_utente = new_vis_utente,
san_utente = new_san_utente,
nnb_utente = new_nnb_utente,
unnb_utente = new_unnb_utente,
vac_utente = new_vac_utente,
tem_utente = new_tem_utente,
res_utente = new_res_utente
)
new_utente.save()
return render(request, 'utenti/add-utenti.html', {
'form': UtenteForm(),
'success': True
})
else:
form = UtenteForm()
return render(request, 'utenti/add-utenti.html', {
'form': UtenteForm()
})
# Modify and edit utente
def modifica_utenti(request, pk):
if request.method == 'POST':
utente= Utente.objects.get(pk=pk)
form = UtenteForm(request.POST, instance=utente)
if form.is_valid():
form.save()
return render(request, 'utenti/mod-utenti.html',{
'form': form,
'success': True
})
else:
utente = Utente.objects.get(pk=pk)
form = UtenteForm(instance=utente)
return render(request, 'utenti/mod-utenti.html', {
'form': form
})
# To delete utente
def delete_utente(request, pk):
if request.method == 'POST':
utente = Utente.objects.get(pk=pk)
utente.delete()
return HttpResponseRedirect(reverse('utenti'))
# View utente
def view_utente(request, pk):
utente = Utente.objects.get(pk=pk)
return HttpResponseRedirect(reverse('index'))
template file
{% extends "utenti/base.html" %}
{% block body %}
<h3 class="text-center m-4">Add new utente</h3>
{% if success %}
<div class="alert alert-success" role="alert">
Added successfully.
Go to the list.
</div>
{% else %}
<div class="row justify-content-center">
<div class="col-6">
<div class="card bg-light mb-3">
<div class="card-header">
<i class="fa-solid fa-address-card fa-lg"></i> Create utente
</div>
<div class="card-body">
<form action="{% url 'aggiungi-utenti' %}" method="POST">
{% csrf_token %}
{{ form.as_p }}
<button type="submit" class="btn btn-primary">Add</button>
Cancel
</form>
</div>
</div>
</div>
</div>
{% endif %}
{% endblock %}
Try changing your view to output the validation errors if is_valid() is false. This will help you narrow it down.
error outputs raw HTML
errors.as_data() outputs a dictonary (might be easier to read)
# Add new utente
def aggiungi_utente(request):
if request.method == 'POST':
form = UtenteForm(request.POST)
if form.is_valid():
new_id_utente = form.cleaned_data ['id_utente']
new_gen_utente = form.cleaned_data ['gen_utente']
new_age_utente = form.cleaned_data ['age_utente']
new_con_utente = form.cleaned_data ['con_utente']
new_per_utente = form.cleaned_data ['per_utente']
new_pres_utente = form.cleaned_data ['pres_utente']
new_doc_utente = form.cleaned_data ['doc_utente']
new_vis_utente = form.cleaned_data ['vis_utente']
new_san_utente = form.cleaned_data ['san_utente']
new_nnb_utente = form.cleaned_data ['nnb_utente']
new_usnnb_utente = form.cleaned_data ['unnb_utente']
new_vac_utente = form.cleaned_data ['vac_utente']
new_tem_utente = form.cleaned_data ['tem_utente']
new_res_utente = form.cleaned_data ['res_utente']
new_utente = Utente(
id_utente = new_id_utente,
gen_utente = new_gen_utente,
age_utente = new_age_utente,
con_utente = new_con_utente,
per_utente = new_per_utente,
pres_utente = new_pres_utente,
doc_utente = new_doc_utente,
vis_utente = new_vis_utente,
san_utente = new_san_utente,
nnb_utente = new_nnb_utente,
unnb_utente = new_unnb_utente,
vac_utente = new_vac_utente,
tem_utente = new_tem_utente,
res_utente = new_res_utente
)
new_utente.save()
return render(request, 'utenti/add-utenti.html', {
'form': UtenteForm(),
'success': True
})
else:
print(form.error)
print(form.errors.as_data())
else:
form = UtenteForm()
return render(request, 'utenti/add-utenti.html', {
'form': UtenteForm()
})
Also if you just do form.save() it'll do all that cleaned_data stuff for you:
# Add new utente
def aggiungi_utente(request):
if request.method == 'POST':
form = UtenteForm(request.POST)
if form.is_valid():
form.save()
return render(request, 'utenti/add-utenti.html', {
'form': UtenteForm(),
'success': True
})
else:
print(form.error)
print(form.errors.as_data())
else:
form = UtenteForm()
return render(request, 'utenti/add-utenti.html', {
'form': UtenteForm()
})
Your view is doing too much work: a Django form can perfectly handle creating an object itself:
from django.shortcuts import redirect
def aggiungi_utente(request):
if request.method == 'POST':
form = UtenteForm(request.POST)
if form.is_valid():
form.save()
return redirect('utenti')
else:
form = UtenteForm()
return render(request, 'utenti/add-utenti.html', {'form': form})
By passing the invalid form to the rendering function again, it will render the problem with the form.
Note: In case of a successful POST request, you should make a redirect
[Django-doc]
to implement the Post/Redirect/Get patternĀ [wiki].
This avoids that you make the same POST request when the user refreshes the
browser.

redirect on the same post_id after edit post

I have created a forum website in Django where users can post Questions/Answers and edit them.
After editing the reply I want to redirect the user to the currently edited post page. like if user
edit reply which has been posted on the question with id 4 (which url is (http://127.0.0.1:8000/discussion/4)) then after edited it should redirect to the same URL. After editing, and deleting the reply I am redirecting the user to the forum homepage but I want to redirect to the /discussion/{post_id} URL(which is URL of the particular post on which reply being edited and deleted)
urls.py
app_name = "dashboard"
urlpatterns = [
path('', views.index, name="index"),
path('user_home', views.user_home, name="user_home"),
path('admin_home', views.admin_home, name="admin_home"),
path("forum", views.forum, name="forum"),
path("discussion/<int:myid>", views.discussion, name="discussion"),
path("showallusers", views.show_all_users, name="showallusers"),
path('delete_user/<int:pk>', views.delete_user, name="delete_user"),
path('delete_post/<int:pk>', views.delete_post, name="delete_post"),
path('delete_reply/<int:pk>', views.delete_reply, name="delete_reply"),
path('upload_notes', views.upload_notes, name='upload_notes'),
path('view_mynotes', views.view_mynotes, name='view_mynotes'),
path('delete_mynotes/<int:pk>/', views.delete_mynotes, `name='delete_mynotes'), `
path('pending_notes', views.pending_notes, name='pending_notes'),
path('assign_status/<int:pk>', views.assign_status, name='assign_status'),
path('accepted_notes', views.accepted_notes, name='accepted_notes'),
path('rejected_notes', views.rejected_notes, name='rejected_notes'),
path('all_notes', views.all_notes, name='all_notes'),
path('delete_notes/<int:pk>', views.delete_notes, name='delete_notes'),
path('delete-records/', views.delete_notes, name='delete_notes'),
path('view_allnotes', views.view_allnotes, name='view_allnotes'),
path('notessharing', views.notessharing, name='notessharing'),
path('edit_post/<int:pk>/', views.edit_post, name='edit_post'),
path('edit_reply/<int:pk>/', views.edit_reply, name='edit_reply'),
]
delete_reply code
def delete_reply(request, pk=None):
reply = Replie.objects.filter(id=pk)
reply.delete()
return redirect('/forum')
After deleting a reply from a post I want to redirect to the same post.
models.py
class Post(models.Model):
user1 = models.ForeignKey(User, on_delete=models.CASCADE, default=1)
post_id = models.AutoField
post_content = models.TextField(max_length=5000,verbose_name="")
timestamp= models.DateTimeField(default=now)
image = models.ImageField(upload_to="images",default="")
def __str__(self):
return f'{self.user1} Post'
class Replie(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, default=1)
reply_id = models.AutoField
reply_content = models.TextField(max_length=5000,verbose_name="")
post = models.ForeignKey(Post, on_delete=models.CASCADE, default='')
timestamp= models.DateTimeField(default=now)
image = models.ImageField(upload_to="images",default="")
def __str__(self):
return f'{self.user1} Post'
views.py
def forum(request):
user = request.user
profile = Profile.objects.all()
if request.method=="POST":
form=PostContent(request.POST)
if form.is_valid():
user = request.user
image = request.user.profile.image
content = request.POST.get('post_content','')
post = Post(user1=user, post_content=content, image=image)
post.save()
messages.success(request, f'Your Question has been posted successfully!!')
return redirect('/forum')
else:
form=PostContent()
posts = Post.objects.filter().order_by('-timestamp')
form= PostContent()
context={
'posts':posts,
'form':form
}
return render(request, "forum.html",context)
def discussion(request, myid):
post = Post.objects.filter(id=myid).first()
replies = Replie.objects.filter(post=post)
if request.method=="POST":
form=ReplyContent(request.POST)
if form.is_valid():
user = request.user
image = request.user.profile.image
desc = request.POST.get('reply_content','')
post_id =request.POST.get('post_id','')
reply = Replie(user = user, reply_content = desc, post=post, image=image)
reply.save()
messages.success(request, f'Your Reply has been posted successfully!!')
return redirect(f'/discussion/{post_id}')
else:
form=ReplyContent()
form= ReplyContent()
return render(request, "discussion.html", {'post':post, 'replies':replies,'form':form})
def edit_reply(request, pk):
reply = Replie.objects.get(id=pk)
if request.method == 'POST':
form = UpdateReplyForm(request.POST, instance=reply)
if form.is_valid():
form.save()
messages.success(request,"Reply updated successfully!")
return redirect('/forum')
else:
form = UpdateReplyForm(instance=reply)
context = {
'form': form
}
return render(request, 'edit_reply.html', context)
edit_post view
def edit_post(request, pk):
post = Post.objects.get(id=pk)
if request.method == 'POST':
form = UpdatePostForm(request.POST, instance=post)
if form.is_valid():
form.save()
messages.success(request, "Post updated successfully!")
return redirect('/forum')
else:
form = UpdatePostForm(instance=post)
context = {
'form': form
}
return render(request, 'edit_post.html', context)
Currently, after editing the reply, I am redirecting the user to the post home page but I want to redirect to /discussion/{post_id}.
Template code:
edit_reply.html
{% load static %}
{% block body %}
{% load crispy_forms_tags %}
<div class="container ">
<form method="POST">
<div class="form-group">
{% csrf_token %}
<fieldset class="form-group">
<legend class="border-bottom mb-4 mt-4 f2" >Update Reply</legend>
</fieldset>
<label style="font-size:1rem; font-weight:bold;">Reply Content</label>
{{form|crispy}}
<input type="hidden" name="post_id" value="{{post_id}}">
<div class="form-group">
<button href="" class="btn btn-primary" type="Update">
Update
</button>
</div>
</div>
</form>
</div>
{% endblock body %}
You can redirect it to discussion view with its pk by passing args=[reply.post.id] in edit_reply view.
Try this:
views.py
from django.shortcuts import render, redirect
from django.urls import reverse
def edit_reply(request, pk):
reply = Replie.objects.get(id=pk)
if request.method == 'POST':
form = UpdateReplyForm(request.POST, instance=reply)
if form.is_valid():
form.save()
messages.success(request, "Reply updated successfully!")
return redirect(reverse('dashboard:discussion', args=[reply.post.id]))
else:
form = UpdateReplyForm(instance=reply)
context = {
'form': form
}
return render(request, 'home/edit_reply.html', context)
Note: Forms in django required Form to be the suffix, so it will be better if it changed to PostContentForm and ReplyContentForm from PostContent and ReplyContent respectively.
It must be return f'{self.user} Post' not
return f'{self.user`} Post'
As it is not any field in Replie model.
Note: ForeignKey's names are generally written in its own name and that too in snake_case, it will be better if you change user1 to user in Post model.
For better understanding:
If table name is PizzaTopingCategory so while creating ForeignKey you should name it as pizza_toping_category=models.ForeignKey(PizzaTopingCategory, on_delete=models.CASCADE)
Edit:
You need to find out post_id, so you can send it through:
Try this in the delte_reply view:
def delete_reply(request, pk=None):
reply = Replie.objects.filter(id=pk)
reply_instance = get_object_or_404(Replie,id=pk)
post_pk=reply_instance.post.id
reply.delete()
return redirect(reverse('dashboard:discussion', args=[post_pk]))
For passing pk in discussion view, you should write return redirect(reverse('dashboard:discussion', args=[reply.post.id])) in edit_post view:
views.py
def edit_post(request, pk):
post = Post.objects.get(id=pk)
if request.method == 'POST':
form = UpdatePostForm(request.POST, instance=post)
if form.is_valid():
form.save()
messages.success(request, "Post updated successfully!")
return redirect(reverse('dashboard:discussion', args=[post.id]))
else:
form = UpdatePostForm(instance=post)
context = {
'form': form
}
return render(request, 'home/edit_post.html', context)

django-forms not rendering errors

I'm having issues rendering errors in my form, when the form is invalid, it just reloads the page and the errors don't show.
I want to show the errors, like showing a text saying that the email is invalid, or that the phone number contain invalid characters
Here's my code:
views.py
def contact(request):
form_class = ContactForm
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'
, '')
form_content = request.POST.get(
'content'
, '')
# Email the profile with the
# contact information
template = get_template('contact_form.txt')
context = Context({
'contact_name': contact_name,
'contact_email': contact_email,
'contact_phone': contact_phone,
'form_content': form_content,
})
content = template.render(context)
email = EmailMessage(
"Novo contato pelo site",
content,
"email#gmail.com",
['myemail#hotmail.com'],
headers={'Reply-To': contact_email}
)
email.send()
print(form.cleaned_data)
else:
print(form)
return render(request, 'info/contact_us.html', {
'form': form_class,
})
forms.py
class ContactForm(forms.Form):
contact_name = forms.CharField(max_length=150,
label="Nome",
required=True,)
contact_email = forms.EmailField(max_length=150,
label="Email",
required=True,)
contact_phone = forms.RegexField(max_length=12,
label="Fone",
required=False,
regex=r'[0-9]+',)
content = forms.CharField(max_length=10000,
required=True,
widget=forms.Textarea,)
def __init__(self, *args, **kwargs):
super(ContactForm, self).__init__(*args, **kwargs)
self.helper = FormHelper(self)
self.helper.form_id = 'id-form'
self.helper.form_class = 'blueForms'
self.helper.form_method = 'post'
self.helper.form_action = ''
self.helper.add_input(Submit('submit', 'Submit'))
self.fields['contact_name'].label = "Name:"
self.fields['contact_email'].label = "Email:"
self.fields['contact_phone'].label = "Phone:"
self.fields['content'].label = "Message:"
def clean(self):
cleaned_data = super(ContactForm, self).clean()
contact_name = cleaned_data.get("contact_name")
contact_email = cleaned_data.get("contact_email")
contact_phone = cleaned_data.get("contact_phone")
content = cleaned_data.get("content")
if 'asd' not in contact_email:
raise forms.ValidationError("Invalid Email")
contact_us.html
<div id="form" class="col-sm-6">
{% crispy form form.helper %}
</div>
Bug is on this line
return render(request, 'info/contact_us.html', {
'form': form_class,
})
When GET method is called it loads the Empty form that is form=form_class(), on POST method it should be form=form_class(request.POST). As per the above code, it is again loading fresh form
Add your return statement inside your POST block also
return render(request, 'info/contact_us.html', {
'form': form_class(request.POST),
})
or
return render(request, 'info/contact_us.html', {
'form': form,
})

How to change this regular html form into django form?

I want to change the following HTML form:
#transaction.atomic
def Register(request):
if request.method == "POST":
fname = request.POST['first_name']
lname = request.POST['last_name']
mobile = request.POST['mobile']
"""This section replaces multiple characters with blank value
so that the mobile number has nothing except numeric values
"""
rep = ['+', '-', ' ', '.']
for i in rep:
mobile = mobile.replace(i, '')
company = request.POST['company']
email = request.POST['email']
u = User.objects.create_user(mobile, email, '1234', first_name=fname, last_name=lname)
u.save()
p = UserProfile.objects.create(user=u, company=company, mobile=mobile)
p.save()
return HttpResponse("Registration complete! Please head over to the <a href='/login/'>login page</a> to start using your SMS panel.")
return render(request, "message/register.html", {})
Into a Django form mainly because I need to learn how to use them, also I need all the fields to be filled up before the registration completes, I don't want any optional fields. The following is what I've come up with from the documentation.
views.py
#transaction.atomic
def Register(request):
if request.method == "POST":
form = RegisterForm(request.POST)
if form.is_valid():
# I guess this is where I need help. Thanks.
else:
form = RegisterForm()
return render(request, "message/register.html", {'form': form})
register.html
<form method="post" action="">
{% csrf_token %}
{{ form }}
<input type="submit" value="Register"/>
</form>
You can create a form RegisterForm and add the process of cleaning of mobile to clean_mobile function in forms.py. Then in your views.py, you can access all the form data using form.cleaned_data dictionary.
You can do something like below:
forms.py
from django import forms
class RegisterForm(forms.Form):
first_name = forms.CharField(max_length=100)
last_name = forms.CharField(max_length=100)
mobile = forms.CharField()
company = forms.CharField(max_length=100)
email = forms.EmailField()
def clean_mobile(self):
mobile = self.cleaned_data['mobile']
rep = ['+', '-', ' ', '.']
for i in rep:
mobile = mobile.replace(i, '')
return mobile
views.py
#transaction.atomic
def Register(request):
if request.method == "POST":
form = RegisterForm(request.POST)
if form.is_valid():
u = User.objects.create_user(form.cleaned_data['mobile'], form.cleaned_data['email'], '1234', first_name=form.cleaned_data['first_name'], last_name=form.cleaned_data['last_name'])
u.save()
p = UserProfile.objects.create(user=u, company=form.cleaned_data['company'], mobile=form.cleaned_data['mobile'])
p.save()
return HttpResponse("Registration complete! Please head over to the <a href='/login/'>login page</a> to start using your SMS panel.")
else:
form = RegisterForm()
return render(request, "message/register.html", {'form': form})
after if form.is_valid() == True django creates a cleaned_data method with which you can call for the cleaned form data into your view.
You might want something like this:
def Register(request):
if request.method == "POST":
form = RegisterForm(request.POST)
if form.is_valid():
fname = form.cleaned_data.get('first_name')
lname = form.cleaned_data.get('last_name')
https://docs.djangoproject.com/en/1.8/ref/forms/api/#django.forms.Form.is_valid
also what does your Form object look like in forms.py?

Categories