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,
})
Related
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.
I am working on a social website and after creating a class to render the user's profile in detail. The path that render all posts and all profiles aren't working anymore and I get the same error and when I uncomment the code from line 21 to 24 (def get_object) function it says "Does Not Exist at /posts/"
Profile matching query does not exist.
Page not found (404)
No profile found matching the query
Request Method: GET
Request URL: http://127.0.0.1:8000/posts/
Raised by: network.views.<class 'network.views.ProfileDetailView'>
Using the URLconf defined in project4.urls, Django tried these URL patterns, in this order:
admin/
[name='index']
login [name='login']
logout [name='logout']
register [name='register']
<slug>/ [name='profile-view']
The current path, posts/, matched the last one.
"
Urls:
urlpatterns = [
path("", views.index, name="index"),
path("login", views.login_view, name="login"),
path("logout", views.logout_view, name="logout"),
path("register", views.register, name="register"),
path("<slug>/", ProfileDetailView.as_view(), name="profile-view"),
path("posts/", post_comment_create_view, name="posts"),
path("liked/", like_unlike_post, name="like-post-view"),
path("<pk>/delete", PostDeleteView.as_view(), name="post-delete"),
path("<pk>/update", PostUpdateView.as_view(), name="post-update"),
path("invites/", invites_received_view, name="invites-view"),
path("allprofiles/", ProfileListView.as_view(), name="all-profiles-view"),
path("send-invite/", send_invitation, name="send-invite"),
path("remove-friend/", remove_friends, name="remove-friend"),
path("invites/accept/", accept_invitation, name="accept-invite"),
path("invites/reject/", reject_invitation, name="reject-invite"),
]
Views:
from .models import Relationship, Post, Profile, Like
from django.views.generic import TemplateView, View, UpdateView, DeleteView, ListView, DetailView
from .forms import ProfileModelForm, PostModelForm, CommentModelForm
class ProfileDetailView(DetailView):
model = Profile
template_name = 'network/profile.html'
def get_object(self, slug=None):
slug = self.kwargs.get('slug')
profile = Profile.objects.get(slug=slug)
return profile
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
user = User.objects.get(username__iexact=self.request.user)
profile = Profile.objects.get(user=user)
rel_r = Relationship.objects.filter(sender=profile)
rel_s = Relationship.objects.filter(receiver=profile)
rel_receiver = []
rel_sender = []
for item in rel_r:
rel_receiver.append(item.receiver.user)
for item in rel_s:
rel_sender.append(item.sender.user)
context["rel_receiver"] = rel_receiver
context["rel_sender"] = rel_sender
context["posts"] = self.get_object().get_all_authors_posts()
context["len_posts"] = True if len(self.get_object().get_all_authors_posts()) > 0 else False
return context
class MyProfileView(TemplateView):
template_name = 'network/my_profile.html'
def index(request):
qs = Post.objects.all()
context = {
'hello': 'hello world!',
'qs':qs,
}
return render(request, "network/index.html", context)
def profile_view(request):
profile = Profile.objects.get(user=request.user)
form = ProfileModelForm(request.POST or None, request.FILES or None, instance=profile)
confirm = False
if request.method == 'POST':
if form.is_valid():
form.save()
confirm = True
context = {
'profile': profile,
'form': form,
'confirm': confirm,
}
return render(request, 'network/profile.html', context)
def invites_received_view(request):
profile = Profile.objects.get(user=request.user)
qs = Relationship.objects.invitations_received(profile)
results = list(map(lambda x: x.sender, qs))
is_empty = False
if len(results) == 0:
is_empty = True
context = {
'qs':results,
'is_empty': is_empty,
}
return render(request, 'network/invites.html', context)
def accept_invitation(request):
if request.method =='POST':
pk = request.POST.get('profile_pk')
sender = Profile.objects.get(pk=pk)
receiver = Profile.objects.get(user=request.user)
rel = get_object_or_404(Relationship, sender=sender, receiver=receiver)
if rel.status == 'send':
rel.status = 'accepted'
rel.save()
return redirect('invites-view')
def reject_invitation(request):
if request.method=="POST":
pk = request.POST.get('profile_pk')
receiver = Profile.objects.get(user=request.user)
sender = Profile.objects.get(pk=pk)
rel = get_object_or_404(Relationship, sender=sender, receiver=receiver)
rel.delete()
return redirect('invites-view')
def invite_profiles_list_view(request):
user = request.user
qs = Profile.objects.get_all_profiles_to_invite(user)
context = {'qs': qs}
return render(request, 'network/to_invite_list.html', context)
def profiles_list_view(request):
user = request.user
qs = Profile.objects.get_all_profiles(user)
context = {'qs': qs}
return render(request, 'network/profile_list.html', context)
class ProfileListView(ListView):
model = Profile
template_name = 'network/profile_list.html'
context_object_name = 'qs'
def get_queryset(self):
qs = Profile.objects.get_all_profiles(self.request.user)
return qs
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
user = User.objects.get(username__iexact=self.request.user)
profile = Profile.objects.get(user=user)
rel_r = Relationship.objects.filter(sender=profile)
rel_s = Relationship.objects.filter(receiver=profile)
rel_receiver = []
rel_sender = []
for item in rel_r:
rel_receiver.append(item.receiver.user)
for item in rel_s:
rel_sender.append(item.sender.user)
context["rel_receiver"] = rel_receiver
context["rel_sender"] = rel_sender
context["is_empty"] = False
if len(self.get_queryset()) == 0:
context["is_empty"] = True
return context
def send_invitation(request):
if request.method == 'POST':
pk = request.POST.get('profile_pk')
user = request.user
sender = Profile.objects.get(user=user)
receiver = Profile.objects.get(pk=pk)
rel = Relationship.objects.create(sender=sender, receiver=receiver, status='send')
return redirect(request.META.get('HTTP_REFERER'))
return redirect('profile')
def remove_friends(request):
if request.method == 'POST':
pk = request.POST.get('profile_pk')
user = request.user
sender = Profile.objects.get(user=user)
receiver = Profile.objects.get(pk=pk)
rel = Relationship.objects.get(
(Q(sender=sender) & Q(receiver=receiver)) | (Q(sender=receiver) & Q(receiver=sender))
)
rel.delete()
return redirect(request.META.get('HTTP_REFERER'))
return redirect('profile')
def like_unlike_post(request):
user = request.user
if request.method == 'POST':
post_id = request.POST.get('post_id')
post_obj = Post.objects.get(id=post_id)
profile = Profile.objects.get(user=user)
if profile in post_obj.liked.all():
post_obj.liked.remove(profile)
else:
post_obj.liked.add(profile)
like, created = Like.objects.get_or_create(user=profile, post_id=post_id)
if not created:
if like.value=='Like':
like.value='Unlike'
else:
like.value='Like'
else:
like.value='Unlike'
post_obj.save()
like.save()
return redirect('posts')
def post_view_json(request):
qs = Post.objects.all()
data = serializers.serialize('json', qs)
return JsonResponse({'data': data})
def profile_test_view(request):
profile = Profile.objects.get(user=request.user)
return render(request, "network/profile_test.html", {'profile':profile})
def post_comment_create_view(request):
qs = Post.objects.all()
profile = Profile.objects.get(user=request.user)
#Setting up pagination
p = Paginator(qs, 5)
page = request.GET.get('page')
post_list = p.get_page(page)
#Post form, comment form
p_form = PostModelForm()
c_form = CommentModelForm()
post_added = False
profile = Profile.objects.get(user=request.user)
if 'submit_pForm' in request.POST:
print(request.POST)
p_form = PostModelForm(request.POST, request.FILES)
if p_form.is_valid():
instance = p_form.save(commit=False)
instance.author = profile
instance.save()
p_form = PostModelForm()
post_added = True
if 'submit_cForm' in request.POST:
c_form = CommentModelForm(request.POST)
if c_form.is_valid():
instance = c_form.save(commit=False)
instance.user = profile
instance.post = Post.objects.get(id=request.POST.get('post_id'))
instance.save()
c_form = CommentModelForm()
context = {
'qs': qs,
'profile': profile,
'p_form': p_form,
'c_form': c_form,
'post_added': post_added,
'post_list': post_list,
}
return render(request, 'network/posts.html', context)
class PostDeleteView(DeleteView):
model = Post
template_name = 'network/confirmDelete.html'
success_url = reverse_lazy('posts')
def get_object(self, *args, **kwargs):
pk = self.kwargs.get('pk')
obj = Post.objects.get(pk=pk)
if not obj.author.user == self.request.user:
messages.warning(self.request, 'You need to be the owner of the post in order to delete it!')
return obj
class PostUpdateView(UpdateView):
form_class = PostModelForm
model = Post
template_name = 'network/update.html'
success_url = reverse_lazy('posts')
def form_valid(self, form):
profile = Profile.objects.get(user=self.request.user)
if form.instance.author == profile:
return super().form_valid(form)
else:
form.add_error(None, "You need to be the owner of the post in order to update it!")
return super().form_invalid(form)
i am finding a problem in saving the user posts from my Django site. Whenever I try to run the submit form, it shows that the form has been submitted but I cant see the post being saved in the data base.
def addPost(request):
form = hacksform(request.POST or None, request.FILES or None)
if request.method == 'POST':
form = hacksform(request.POST or None, request.FILES or None)
if form.is_valid():
try:
newpost = form(commit= False)
image = request.FILES['photo']
newpost.author = request.user
newpost.post_image = image
newpost.save()
newpost.save_m2m()
except:
newposts = form(commit=False)
newpost.author = request.user
newposts.save()
newposts.save_m2m()
return HttpResponseRedirect('/tweaks/tweaks')
return HttpResponseRedirect('/tweaks/tweaks')
and here is my forms.py file
class hacksform(forms.ModelForm):
VIEW_CHOICES = (
("Option", "Choose Option"),
("Public", "To Public"),
("Channels", "To Channels"),
)
title = forms.CharField(widget=forms.TextInput(attrs={'class': 'user-title', 'placeholder': 'Title'}) ,required=True)
content = forms.CharField(widget=forms.Textarea(attrs={'class': 'user-text', 'placeholder': 'Questions'}) ,required=False)
tags = forms.CharField(widget=forms.TextInput(attrs={'class': 'input-tag', 'placeholder': 'Add Tag'}) ,required=False)
audience_privacy = forms.CharField(widget=forms.Select(choices=VIEW_CHOICES,attrs={'id': 'selector'}) ,required=False)
class Meta:
model = hacks
fields = [
'title',
'author',
'tags',
'content',
'post_image',
'audience_privacy'
]
any ideas why I cant post
def addPost(request):
if request.method == 'POST':
form = hacksform(request.POST or None, request.FILES or None)
if form.is_valid():
try:
newpost = form(commit= False)
image = request.FILES['photo']
newpost.author = request.user
newpost.post_image = image
newpost.save()
newpost.save_m2m()
except:
newposts = form(commit=False)
newpost.author = request.user
newposts.save()
newposts.save_m2m()
return HttpResponseRedirect('/tweaks/tweaks')
else:
print("errors",form.errors) # Print the errors on console
return HttpResponseRedirect('/tweaks/tweaks')
I'm using Django Model Form. Can anyone help me validate those fields to get field error using clean()?
The Name field cannot be repeated in the same office, only in a different one.
form.py
class CreateSalesRepForm(forms.ModelForm):
class Meta:
model = CreateSalesRep
fields = ['name', 'office']
widgets = {
'office': forms.Select(attrs={'class': 'form-control', 'placeholder': 'Enter Office'}),
'name': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Enter Name'})
}
UPDATED (form.py) --- Here is the solution, you can use this codes to validate both insert and update form.
def clean(self):
cleaned_data = super().clean()
office = cleaned_data.get("office")
name = cleaned_data.get("name")
duplicates = CreateSalesRep.objects.filter(office=office, name=name)
if (self.instance.pk and None):
duplicates = duplicates.filter(pk=self.instance.pk)
if duplicates.exists():
msg = "Name already exist in office selected"
self.add_error('name', msg)
self.add_error('office', msg)
view.py
def create_salesrep(request):
if request.method == "POST":
form = CreateSalesRepForm(request.POST or None)
if form.is_valid():
form.save()
messages.success(request, 'Successfully Saved!', 'alert-success')
return redirect('sales_rep')
else:
return render(request, 'salesrep/create_salesrep.html', {'form':form})
else:
form = CreateSalesRepForm()
context = {'form':form}
return render(request, 'salesrep/create_salesrep.html', context)
def update_salesrep(request, pk):
srep = CreateSalesRep.objects.get(id=pk)
form = CreateSalesRepForm(instance=srep)
if request.method == "POST":
form = CreateSalesRepForm(request.POST or None, instance=srep)
if form.is_valid():
form.save()
messages.success(request, 'Successfully Updated!', 'alert-success')
return redirect('sales_rep')
else:
return render(request, 'salesrep/update_salesrep.html', {'form':form})
else:
form = CreateSalesRepForm(instance=srep)
return render(request, 'salesrep/update_salesrep.html', {'form':form})
You can validate in the forms:
class CreateSalesRepForm(forms.ModelForm):
class Meta:
model = CreateSalesRep
fields = ['name', 'office']
def clean(self):
cleaned_data = super().clean()
office= cleaned_data.get("office")
name = cleaned_data.get("name")
duplicates = CreateSalesRep.objects.filter(office=office, name=name)
if self.instance.pk:
duplicates = duplicates.filter(pk=self.instance.pk)
if duplicates.exists():
raise forms.ValidationError('Name already in office')
That being said, you could enforce this in the model/db level as well by adding the following to your CreateSalesRep model:
class CreateSalesRep(models.Model):
...
class Meta:
unique_together = ['office', 'name']
You can try following inside your model class
class Meta:
unique_together = [('office', 'name')]
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,
})