Check the form input value to existing value in Django - django

In in my database there are some emails those should be checked with the form value which is entered in email field
models.py
class Friend(models.Model):
email = models.EmailField(max_length=100)
forms.py
class FriendForm(forms.ModelForm):
class Meta:
model = Friend
fields = ['email']
views.py
def check(request):
if request.method == "POST":
form = FriendForm(request.POST)
if form.is_valid():
queryset = Friend.objects.all
return render(request,"two.html",{"queryset":queryset})
else:
form = FriendForm()
return render(request, 'emaill.html', {'form': form})
emaill.html
<body>
<form method="POST">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" name="Submit">
</form>
</body>
two.html
<body>
<h1>found</h1>
{% for obj in queryset %}
{{obj.email}} </br>
{% endfor %}
</body>
when user submited any email that should be checked with models email that means with existing one if matches in should render to two.html it should show connect
if mail does not match with mail that is in database it should show no such mail

Okay, I understand what you are trying to do. You are doing an email search.
def check(request):
if request.method == "POST":
form = FriendForm(request.POST)
if form.is_valid():
email = form.cleaned_data("email")
try:
friend = Friend.objects.get(email=email)
return render(request,"email1.html",
{"friend":friend})
except Friend.DoesNotExist:
return render(request, "email1.html", {"form":form})
If you are interested in connecting them, then you should use the get method of the ModelManager (objects). That will return a single object if it exists.
In your template. As you can see I have saved some typing on an extra template by using conditions in the template.
{% if form %}
#display your form
{% else %}
#display the friend as you want
{% endif %}
I recommend you go slow and do more reading of the documentation. I am here. Note that I changed your queryset to friend. queryset is misleading as it points that you want multiple objects. So in your template you cant iterate, instead you display friend without iterating.
{{ friend }}

Related

why is django returning form.is_valid == false?

Everytime I use this form I get form.is_valid() == False . When I do print(form.errors) I get :
<ul class="errorlist"><li>reservation_code<ul class="errorlist"><li>Client with this Reservation code already exists.</li></ul></li></ul>
But the whole point of the form is to get the details of the reservation, by entering an already existing reservation code. So how can I change this so the form returns valid?
Here is the view:
def reservationView(request):
if request.method == "GET":
return render(request,'aplikacija/reservations.html')
else:
form = ReservationForm(request.POST)
if form.is_valid():
code = form.cleaned_data['reservation_code']
try:
client = Client.objects.filter(reservation_code=code)
tour = client.tour.destination
client.delete()
return render(request,'aplikacija/reservations.html',{'infoMsg':f'You have successfully cancelled your trip to {tour}'})
except:
form = ReservationForm()
return render(request,'aplikacija/cancelReservation.html',{'form':form,'infoMsg':'INVALID RESERVATION CODE'})
else:
form = ReservationForm()
print(form.errors)
return render(request,'aplikacija/cancelReservation.html',{'form':form,'infoMsg':'FORM INVALID'})
This is the model :
class Client(models.Model):
name = models.CharField(max_length=256)
surname = models.CharField(max_length=256)
email = models.CharField(max_length=256)
number_of_guests =models.IntegerField()
tour = models.ForeignKey(Tour,on_delete=models.CASCADE)
total_price = models.DecimalField(decimal_places=2,max_digits=15,default=0)
reservation_code = models.CharField(max_length=50,unique=True)
This is the form class :
class ReservationForm(forms.ModelForm):
class Meta:
model = Client
fields = ('reservation_code',)
widgets = {
'reservation_code':forms.TextInput(attrs={'class':'clientFormField'})
}
And here is the template :
{% extends 'aplikacija/base.html' %}
{% block content %}
<h2 id="mostPopularTitle">Please enter your reservation code</h2>
<form method="POST" action="{% url 'reservation_details' %}" class="contactFormTab clientForm">
{{infoMsg}}
{% csrf_token %}
{{ form.as_p }}
<button type="submit" class="btn">Get reservation details</button>
</form>
{% endblock %}
Does anyone have an idea why the form is always returning invalid?
For this problem as you said
the whole point of the form is to get the details of the reservation,
by entering an already existing reservation code
You are doing it on a wrong way. If you want to get the details based on the reservation_code you need to change some logic.
There is no point on creating a ModelForm but you can use simply Form if you want.
You can change your form method from POST to GET.
<form action="{% url 'reservation_details' %}" class="contactFormTab clientForm">
{{infoMsg}}
<input type='text' name='reservation_code' placeholder='Reservation Code'>
<button type="submit" class="btn">Get reservation details</button>
</form>
Now in the view.
def reservation_view(request):
reservation_code = request.GET.get('reservation_code')
client = Clinet.objects.get(reservation_code=reservation_code)
return render(request, 'your_template', {'client':client}
Now in the template you can get the client details with this reservation_code
{{clinet.name}} {{client.surname}}

Why values are not storing in the table when i have clicked Submit button?

I have created a form for getting the value and placing it in the table. But whenever I click on Submit button, it doesn't store or give any error.It is simply staying in that page itself.
Model.py
class Employee(models.Model):
ename=models.CharField(max_length=120)
eaddress=models.CharField(max_length=120)
eemail=models.CharField(max_length=120)
ephone=models.CharField(max_length=120)
emobile=models.CharField(max_length=120)
eid=models.CharField(max_length=120)
egender=models.CharField(max_length=120)
ehire=models.DateTimeField()
edob=models.DateTimeField()
class Meta:
db_table="employee"
views.py
def employee(request):
emp=Employee.objects.all()
return render(request,'employee.html',{'emp':emp})
def addemployee(request):
if request.method == 'POST':
emp = EmployeeForm(request.POST)
if emp.is_valid():
try:
form.save()
return redirect(employee)
except:
pass
else:
emp = EmployeeForm()
return render(request,'addemployee.html',{'emp':emp})
addemployee.html:
<form method="POST" action="add_employee">
{% csrf_token %}
{{emp.ename}}
{{emp.eemail}}
{{emp.emobile}}
<button type="submit">Submit</button>
</form>
You need to display your form errors in template. So update your view and template like this:
def addemployee(request):
emp = EmployeeForm(request.POST or None)
if request.method == 'POST':
if emp.is_valid():
try:
emp.save()
return redirect(employee)
except Exception as e:
raise e # for debug purpose now
return render(request,'addemployee.html',{'emp':emp})
addemployee.html:
<form method="POST" action="add_employee">
{% csrf_token %}
{{ emp.errors }} // it will render form errors
{{emp.ename}}
{{emp.eemail}}
{{emp.emobile}}
<button type="submit">Submit</button>
</form>
I am assuming your form is not validating because you have many fields like eid, egender etc which are required for saving it in Database. If you are using Modelform, then you can use {{ emp.as_p }} as per form rendering documentation for rendering form instead of {{emp.ename}} {{emp.eemail}} {{emp.emobile}}.

Django: Return to template along with template variables

I am using Django to build a student-teacher portal.
I have two groups of users - teachers and students. If user is a teacher, i need to provide a different template (a form for selecting student's registration number). I followed this link to do the same.
Here are the code snippets:
home.html
{% if is_teacher %}
<p style="color:blue; text-align:center; font-size:160%"><b>Course taken: <span style="color:green">IT000</span></b></p>
<form action="/" method="post" align="center">
{% csrf_token %}
<div align="center">{{ form }}</div>
<input type="submit" value="Get student's results!" class="btn btn-primary" style="margin-top:10px"/>
</form>
{% else %}
<p style="color:blue; text-align:center; font-size:160%"><b>Performance for the subject <span style="color:green">IT000</span> is shown below.</b></p>
{% endif %}
views.py
#login_required(login_url="login/")
def home(request):
is_teacher = request.user.groups.filter(name='teachers').exists()
if is_teacher:
if request.method == 'POST':
form = Regno(request.POST)
if form.is_valid():
selected_reg = Student.objects.filter(regno=request.POST.get('regno'))
return render(request, 'home.html',{'selected_reg': selected_reg,'form':form})
else:
form = Regno()
return render(request, 'home.html', {'form': form,'user':request.user,'is_teacher':is_teacher})
else:
selected_reg = Student.objects.filter(regno=request.user)
return render(request, 'home.html', {'user':request.user,'is_teacher':is_teacher,'selected_reg':selected_reg})
Here, Regno is a Form for the teacher to enter student's registration no.
When a teacher initially logs in, he is displayed the form. However, after he submits the form, it is not displaying the form. It executes the {% else %} part of the template. How do I make sure the is_teacher template variable is passed on to this template after the teacher submits the form?
I read about Django sessions but I'm not sure if it can help.
Instead of passing the is_teacher every time, you should use RequestContext to pass it along with your requests.
Looks like in your post call on form submit, you are not passing is_teacher variable. (in below code)
if form.is_valid():
selected_reg = Student.objects.filter(regno=request.POST.get('regno'))
return render(request, 'home.html',{'selected_reg': selected_reg,'form':form})
You should add is_teacher in above.
Also, better way to handle it via custom template tag -
register = template.Library()
#register.filter(name='has_group')
def has_group(user, group_name):
group = Group.objects.get(name=group_name)
return True if group in user.groups.all() else False
and in the template -
{% if request.user|has_group:'teachers' %}
....
{% else %}
....
{% endif %}
You can avoid passing it with each call. Hope it helps.

Django form is not valid

I am trying to submit a form and it will not pass as is_valid in the view.
The form uses forms.Modelforms which I do not have a lot of experience with.
I checked {{ form.errors }} in the template but didn't get anything back.
I appreciate the time and expertise
Form
class AddSubcategory(forms.ModelForm):
class Meta:
model = Subcategory
fields = ['category']
subcategory_name = forms.CharField(max_length=255)
View
#login_required
#locationed
def add_subcategory(request, location):
subcat_form = AddSubcategory(request.POST)
if subcat_form.is_valid():
submitted_subcat_name = subcat_form.cleaned_data['subcategory_name']
selected_cat = subcat_form.cleaned_data['category']
_, was_created = Subcategory.objects.get_or_create(name=submitted_subcat_name, category=selected_cat)
return HttpResponseRedirect(reverse('manage_cat_subcat', args=(location.slug,)))
else:
cat_form = AddCategory()
subcat_form = AddSubcategory()
return render(request, 'inventory/manage_cat_subcat.html', {'location': location,'cat_form': cat_form,'subcat_form':subcat_form})
Template (form)
<form class="form-inline" action="{% url 'add_subcategory' location.slug %}" method="post">
{% csrf_token %}
{{subcat_form.category}}
{{subcat_form.subcategory_name}}
<button class="btn btn-small" type="submit">Add Subcategory</button>
</form>
You specify in fields that you need id, category and name but you don't put them in your form in your template.
You have only category and subcategory_name.
You can add those two elements in your template OR remove them from the fields list.
Also you don't specify an action for your form, you should give the view where the data from your form should be sent.

Edit a Key/Value Parameters list Formset

I'm looking for a convenient solution to create an 'edit settings' key/values page.
Parameters model :
class Parameter(models.Model):
key = models.CharField(max_length=50)
value = models.CharField(max_length=250)
showInUI = models.SmallIntegerField()
Initial Keys/Values are already inserted in table.
I load them and send them using a model formset factory using these lines :
ParameterFormSet = modelformset_factory(Parameter, extra=0, fields=('key', 'value'))
parameterFormSet = ParameterFormSet(queryset=Parameter.objects.filter(showInUI=1))
return render_to_response('config.html', {'parameterFormSet': parameterFormSet}, context_instance=RequestContext(request))
Template side, when formset is displayed, keys and values are shown as inputs.
I'd like to find a convenient way to display form keys as readonly labels and values as inputs. And, when submited, validate them according django standards.
I've read a lot of stuff, I guess the solution may be a custom widget, but I could find a reliable solution.
Thanks for reading.
EDIT :
Working solution
views.py
def config(request):
ParameterFormSet = modelformset_factory(Parameter, extra=0, fields=('value',))
if request.method == "POST":
try:
formset = ParameterFormSet(request.POST, request.FILES)
except ValidationError:
formset = None
return HttpResponse("ko")
if formset.is_valid():
formset.save()
return HttpResponse("ok")
#ParameterFormSet = modelformset_factory(Parameter, extra=0, fields=('value',))
parameterFormSet = ParameterFormSet(queryset=Parameter.objects.filter(showInUI=1))
return render_to_response('config.html', {'parameterFormSet': parameterFormSet}, context_instance=RequestContext(request))
template
<form method="post">
{% csrf_token %}
{{ parameterFormSet.management_form }}
{% for form in parameterFormSet %}
<div>
{{ form.instance.key }}
{{ form }}
</div>
{% endfor %}
<input type="submit" />
</form>
If you do not want the value to be editable, don't include it in fields when creating the form set.
ParameterFormSet = modelformset_factory(Parameter, extra=0, fields=('value',)) # don't forget the trailing comma after 'value' otherwise it's not a tuple!
In your template, you can then loop through the forms in the form set, and display the key at the same time.
{% for form in parameter_form_set %}
{{ form.instance.key }}{# display the key related to this form #}
{{ form }}{# display the form #}
{% endfor %}