local variable 'search_keyword' referenced before assignment - python

I have been working on a search form and it's giving me this error when i open the url or submit the form.
I am watching a codemy django tutorial and the only thing that is different is that i have some code for pagination i don't know if that's what is affecting it.
base.html
<div class="header-search-wrapper novis_search">
<form method="POST" action="{% url 'listing' %}" name="searchform">
{% csrf_token %}
<div class="custom-form">
<label>Keywords </label>
<input type="text" placeholder="Property Keywords" name="search"/>
<!-- <label >Categories</label>
<select data-placeholder="Categories" name = "home_type" class="chosen-select on-radius no-search-select" >
<option>All Categories</option>
<option>Single-family</option>
<option>Semi-detached</option>
<option>Apartment</option>
<option>Townhomes</option>
<option>Multi-family</option>
<option>Mobile/Manufactured</option>
<option>Condo</option>
</select>
<label style="margin-top:10px;" >Price Range</label>
<div class="price-rage-item fl-wrap">
<input type="text" class="price-range" data-min="10000" data-max="100000000000" name="price-range1" data-step="1" value="1" data-prefix="$₦">
</div> -->
<button type="submit" class="btn float-btn color-bg"><i class="fal fa-search"></i> Search</button>
</div>
</form>
</div>
views.py
def listing(request):
if request.method == 'POST' and 'searchform' in request.POST :
search = request.POST['search']
print(search)
propertys = Property.objects.filter(name__icontains=search)
p = Paginator(Property.objects.order_by('-listed_on'), 2)
page = request.GET.get('page')
propertys = p.get_page(page)
nums = "p" * propertys.paginator.num_pages
return render(request, 'listing.html',{'search_keyword':search,'nums':nums,'propertys':propertys})
else:
p = Paginator(Property.objects.order_by('-listed_on'), 2)
page = request.GET.get('page')
propertys = p.get_page(page)
nums = "p" * propertys.paginator.num_pages
return render(request, 'listing.html',{'propertys':propertys, 'nums':nums})

Related

Django HttpResponseRedirect doesn´t lead to the page

I am working on the CS50 project2 commerce. I try to create a new list but when I click on the submit button, it doesn´t redirect to the index page as I want. Anybody can help please? I get the error message: auctions.models.Category.DoesNotExist: Category matching query does not exist. However I can add list directly from admin page.
views.py
def createlisting(request):
if request.method == "GET":
allCategories = Category.objects.all()
return render(request, "auctions/create.html", {
"categories": allCategories
})
else:
# get the data from the form
title = request.POST["title"]
description = request.POST["description"]
imageurl = request.POST["imageurl"]
price = request.POST["price"]
category = request.POST["category"]
currentuser = request.user
# get the contents
categoryData = Category.objects.get(categoryName=category)
#create new list object
newListing = Listing(
title=title,
description=description,
imageUrl=imageurl,
price=float(price),
category=categoryData,
owner=currentuser
)
newListing.save()
return HttpResponseRedirect(reverse("index"))
create.html
{% extends "auctions/layout.html" %}
{% block body %}
<h2>Create New Listing</h2>
<form action = "{% url 'create' %}" method="POST">
{% csrf_token %}
<div class="form-group">
<label for="title">Title</label>
<input type="text" name="title" class="form-control" id="title" placeholder="Enter title">
</div>
<div class="form-group">
<label for="description">Description</label>
<input type="text" name="description" class="form-control" id="description" placeholder="Enter Description">
</div>
<div class="form-group">
<label for="imageurl">Image URL</label>
<input type="text" name="imageurl" class="form-control" id="imageurl" placeholder="Image Url">
</div>
<div class="form-group">
<label for="price">Price</label>
<input type="number" name="price" class="form-control" id="price" placeholder="Price">
</div>
<div class="form-group">
<label for="category">Choose a Category</label>
<select name="category" id="category">
{% for category in categories %}
<option value="category">{{category}}</option>
{% endfor %}
</select>
</div>
<button type="submit" class="btn btn-success">Create New Listing</button>
</form>
{% endblock %}
Use redirect. And you don't need to use else after returning in the if statement.
from django.shortcuts import redirect
def createlisting(request):
if request.method == "GET":
allCategories = Category.objects.all()
return render(request, "auctions/create.html", {
"categories": allCategories
})
# POST
title = request.POST["title"]
description = request.POST["description"]
imageurl = request.POST["imageurl"]
price = request.POST["price"]
category = request.POST["category"]
currentuser = request.user
# get the contents
categoryData = Category.objects.get(categoryName=category)
#create new list object
newListing = Listing(
title=title,
description=description,
imageUrl=imageurl,
price=float(price),
category=categoryData,
owner=currentuser
)
newListing.save()
return redirect("index")
Try this view:
def createlisting(request):
allCategories=""
if request.method == "GET":
allCategories = Category.objects.all()
else:
# get the data from the form
title = request.POST["title"]
description = request.POST["description"]
imageurl = request.POST["imageurl"]
price = request.POST["price"]
category = request.POST["category"]
currentuser = request.user
# get the contents
categoryData = Category.objects.get(categoryName=category)
#create new list object
newListing = Listing(
title=title,
description=description,
imageUrl=imageurl,
price=float(price),
category=categoryData,
owner=currentuser
)
newListing.save()
return redirect("index")
return render(request, "auctions/create.html", {
"categories": allCategories
})

How to resolve reverse match error in django

I'm new to Django and I cannot understand why this error is popping up:
django.urls.exceptions.NoReverseMatch: Reverse for 'updater' with no arguments not found. 1 pattern(s) tried: ['update/(?P<updating>[0-9]+)$']
[26/Jul/2020 19:05:05] "GET /update/2 HTTP/1.1" 500 127513
my urls:
urlpatterns=[
path('update/<int:updating>',views.update,name='updater'),
]
the html page:
<!DOCTYPE html>
<html lang="en">
<head>
{% load static %}
<title>NEW PRODUCT</title>
</head>
<body>
<div class="bg-contact2" style="background-image: url('images/bg-01.jpg');">
<div class="container-contact2">
<div class="wrap-contact2">
<form class="contact2-form validate-form" method="post" action="{%url 'updater' %}" enctype="multipart/form-data">
{% csrf_token %}
<span class="contact2-form-title">
Provide Product details Below
</span>
<div class="wrap-input2 validate-input" data-validate="type is required">
<input class="input2" type="text" name="type" value="{{details.product_type}}">
<span class="focus-input2" data-placeholder="PRODUCT-TYPE"></span>
</div>
<div class="wrap-input2 validate-input" data-validate = "Name is required">
<input class="input2" type="text" name="name" value="{{details.product_name}}">
<span class="focus-input2" data-placeholder="PRODUCT NAME"></span>
</div>
<div class="wrap-input2 validate-input" data-validate = "description is required">
<textarea class="input2" name="description">{{details.product_description}}</textarea>
<span class="focus-input2" data-placeholder="PRODUCT DESCRIPTION"></span>
</div>
<div class="wrap-input2 validate-input" data-validate = "Price is required">
<input class="input2" type="number" name="price" value="{{details.product_price}}">
<span class="focus-input2" data-placeholder="PRICE"></span>
</div>
<div class="wrap-input2 validate-input" data-validate = "Picture is required">
<label >product sample picture</label>
<input class="input2" type="file" name="picture">
<span class="focus-input2" data-placeholder=""></span>
</div>
<div class="container-contact2-form-btn">
<div class="wrap-contact2-form-btn">
<div class="contact2-form-bgbtn"></div>
<button class="contact2-form-btn">
Update Product Listing
</button>
</div>
</div>
</form>
</div>
</div>
</div>
</body>
</html>
my views:
def update (request,updating):
if request.method=='POST':
product_details=product_info.objects.get(id=updating)
product_details.product_type=request.POST.get('type')
product_details.product_name=request.POST.get('name')
product_details.product_description=request.POST.get('description')
product_details.product_price=request.POST.get('price')
if (len(request.FILES) != 0):
image = request.FILES['picture']
product_details.product_pic = image
product_details.save()
alldetails = product_info.objects.all()
return render(request, 'adminside/editingpage.html', {'editing_details': alldetails})
else:
product_details = product_info.objects.get(id=updating)
return render(request,'adminside/updating.html',{'details':product_details})
def update (request,updating) :
if request.method=='POST' :
product_details=product_info.objects.get(id=updating)
product_details.product_type=request.POST.get('type')
product_details.product_name=request.POST.get('name')
product_details.product_description=request.POST.get('description')
product_details.product_price=request.POST.get('price')
if (len(request.FILES) != 0):
image = request.FILES['picture']
product_details.product_pic = image
product_details.save()
alldetails = product_info.objects.all()
return render(request, 'adminside/editingpage.html', {'editing_details': alldetails})
else:
product_details = product_info.objects.get(id=updating)
return render(request,'adminside/updating.html',{'details':product_details})
def update (request,updating):
if request.method=='POST':
product_details=product_info.objects.get(id=updating)
product_details.product_type=request.POST.get('type')
product_details.product_name=request.POST.get('name')
product_details.product_description=request.POST.get('description')
product_details.product_price=request.POST.get('price')
if (len(request.FILES) != 0):
image = request.FILES['picture']
product_details.product_pic = image
product_details.save()
alldetails = product_info.objects.all()
return render(request, 'adminside/editingpage.html', {'editing_details': alldetails})
else:
product_details = product_info.objects.get(id=updating)
return render(request,'adminside/updating.html',{'details':product_details})
I think it has something to do with passing the id of the product in the url, but I'm not sure about how to resolve it.
you have not put any argument in the url you have to put argument in the form action for updating like this
<form class="contact2-form validate-form" method="post" action="{%url 'updater' updating='ANYVALUE' %}" enctype="multipart/form-data">
because you haven't specify any value your url is not matching
This urlpattern update/ takes an int route parameter
path('update/<int:updating>',views.update,name='updater'),
In your template, you're trying to reverse updater with no included argument. So it's trying to reverse to a urlpattern of update/ which it can't find because you only have a path for update/<int:updating>
{%url 'updater' %}
You will need to change it to the following as you gave the context object the name details and you can access
{%url 'updater' details.id %}

How to have single view for multiple HTML forms - Django

This is my view.So I want to keep 2 different HTML forms in same view ,But I am unable to do so beacuse whenever I add 1 form , I get the error of other on being none.
def home(request):
name = None
if request.method == 'POST':
name = request.POST.get('name')
choices = request.POST.get('choices')
subtest = request.POST.get('subtest')
reference = request.POST.get('reference')
unit = request.POST.get('unit')
test = Test()
test.name = name
test.save()
subtest = Subtest()
subtest.test = Test.objects.get(name=choices)
subtest.name = subtest
subtest.unit = unit
subtest.reference_value = reference
subtest.save()
# print(name)
return redirect('home')
return render(request,'main.html',{})
I have got 2 different forms . I didn't use django forms because I wanted to try something new.
MY FIRST FORM
<form method="POST">
{% csrf_token %}
<div class="icon-holder">
<i data-modal-target="test-popup" class="icon-cross"></i>
</div>
<div class="input-group">
<input type="text" name="name" placeholder="Test name" />
</div>
<div class="button-group">
<button type="submit">Submit</button>
</div>
</form>
MY SECOND FORM
<form method="POST">
{% csrf_token %}
<div class="icon-holder">
<i data-modal-target="menu-test-popup" class="icon-cross"></i>
</div>
<div class="input-group">
<label for="test-select">Test Name:</label>
<select name="choices" id="test-select">
{% for test in test %}
<option value="{{test.name}}" name='choices'>{{test.name|title}}</option>
{% endfor %}
</select>
</div>
<div class="input-group">
<input type="text" name="subtest" placeholder="SubTest name" />
</div>
<div class="input-group">
<input type="text" name="reference" placeholder="Reference rate" />
</div>
<div class="input-group">
<input type="text" name="unit" placeholder="Unit" />
</div>
<div class="button-group">
<button type="submit">Submit</button>
</div>
</form>
first form
<form method="POST">
...
<input name="form_type" value="first-form" type="hidden">
</form>
second form
<form method="POST">
...
<input name="form_type" value="second-form" type="hidden">
</form>
view function
def view(request):
if method == "POST":
form_type = request.POST.get('form_type')
if form_type == "first-form":
# first form's process
elif form_type == "second-form":
#second form's process
You have two forms here, when you submit the second form, only the fields from the second form gets submitted.
so from this line
name = request.POST.get('name')
name will become None. But I believe your Test model does not take any None value for name field( the reason for you " IntegrityError at / NOT NULL constraint failed: lab_test.name ").
To overcome this, first check if there is any value for 'name' then proceed with creating the test instance
if name:
test = Test()
test.name = name
test.save()
Similarly check if the other fields are present for the second form before creating and saving the instance.

Trying to pass url in form action

I'm new in django and i'm stuck now.
I'm trying to pass the url in form [action] attribute that would go to my edit function defined in [views.py] file and do it's job but whenever I try to pass the url [NoReverseMatch] is shown.
This is what i tried to do:
<div class="modal fade" id="editform" role="dialog">
<div class="modal-dialog">
<div class = "modal-content">
<div class = "modal-header">
<button type = "button" class = "close" data-dismiss="modal">×</button>
<h3 class="modal-title">
<b>Edit Information</b>
</h3>
</div>
<div class = "modal-body">
<form action="{% url 'studentapp:editrow' rowid=id %}" id="editform" method="POST">
{% csrf_token %}
<div class = "form-group">
<label for = "your_name">
Your name:
</label>
<input class = "form-control" id="new_name" type = "text" name="name" value="{{ student_detail.name }}" placeholder="Enter your name">
</div>
<div class="form-group">
<label for = "course_name">
Course:
</label>
<input id="new_course" class = 'form-control' type = "text" name="course" value="{{ student_detail.course }}" placeholder="Enter your course">
</div>
<div class = "form-group">
<label for = "rollno">
Roll No.:
</label>
<input id="new_rollno" type = "text" class = 'form-control' name="roll" value="{{ student_detail.roll }}" placeholder="Enter your roll number">
</div>
<div class = "form-group">
<label for ="addr">
Address:
</label>
<input id="new_address" type = "text" name="address" class = 'form-control' value="{{ student_detail.address }}" placeholder="Enter your address"/>
</div>
<input type = "submit" value="Update" id="update" class = "btn btn-success" style="font-size:18px;" />
</form>
</div>
</div>
</div>
</div>
In my urls.py I've used the following url:
url(r'^editrow/(?P<rowid>[0-9]+)/$', views.editrow, name='editrow'),
My [editrow] view looks something like this:
def editrow(request, rowid):
item = get_object_or_404(Studentapp, rowid=id)
print item
if request.method=="POST":
form = EntryForm(request.POST, instance=item)
if form.is_valid():
post=form.save(commit=False)
post.save()
return HttpResponseRedirect(reverse('studentapp:index'),rowid.id)
else:
form=EntryForm(instance=item)
return render(request, 'index.html',{'form':form})
else:
form=EntryForm(instance=item)
return render(request, 'index.html',{'form':form})
View that render's the template:
def index(request):
context = {}
latest_student = Studentapp.objects.order_by('pub_date')
context.update({
'latest_student': latest_student
})
response = {"status": False, "errors": []}
if request.is_ajax():
id = request.POST['id']
response = {}
response['status'] = False
student_detail = Studentapp.objects.filter(id=id).first()
context = {
"student_detail": student_detail
}
template = render_to_string("studentapp/_edit_student.html", context)
response['template'] = template
response['status'] = True
return HttpResponse(json.dumps(response), content_type="applicaton/json")
return render(request, "studentapp/index.html", context)
What i'm doing in crud is:
1) make an [edit] button in table through for loop.
2) when i click [edit] button a pre-populated form shows up(which i'm getting).
3) After i click the pre-populated form i want to edit that form and save it and updated data is reflected in my django db.
Thanks to #Alasdair, I looked in my code what he was trying to tell me and i got the answer.
The url that i was trying to pass through my action attribute was wrong. Here's what i did.
<form action="{% url 'studentapp:editrow' rowid=student_detail.id %}" id="editform" method="POST">
Through "student_detail" i'm able to get pre-populated form as i mentioned above. i used the same to get the id and pass it to my "editrow" view.
It's working for me now.
It seems like you never add id to your context in your view index. So the template does not have that variable available.
You need to add that id to your context.
Just like #Alasdair pointed out in the comments.

Implement search in django

I have this html search form and I want to link it to my search view to make it work.
<form class="navbar-form navbar-left" role="search" >
<div class="form-group">
<input type="text" class="form-control" placeholder="Search" action = "/search/">
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
Here is the views.
def searchResults(request, drname):
# drname = request.GET.get('drname')
doctors = Doctor.objects.filter(name__contains=drname)
clinic = Doctor.objects.filter(clinic__name__contains=drname)
d = getVariables(request)
d['doctors'] = doctors
d['doctors_by_clinic'] = doctors
return render_to_response('meddy1/doclistings.html',d)
urls.py
url(r'^search/(?P<drname>\w+)/$', views.searchResults, name='searchResults'),
Html. <form> must have action attribute, not <input>. Also, send search string as get parameter, don't include it in url (add name attribute to <input>):
<form class="navbar-form navbar-left" role="search" action="/search/">
<div class="form-group">
<input type="text" class="form-control" placeholder="Search" name="drname">
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
urls.py. Drop this part (?P<drname>\w+)/:
url(r'^search/$', views.searchResults, name='searchResults'),
views.py. Get search string from GET parameter:
def searchResults(request):
drname = request.GET.get('drname')
doctors = Doctor.objects.filter(name__contains=drname)
clinic = Doctor.objects.filter(clinic__name__contains=drname)
d = getVariables(request)
d['doctors'] = doctors
d['doctors_by_clinic'] = doctors
return render_to_response('meddy1/doclistings.html',d)
action goes in the form element, not the input.

Categories