Django Search query within multiple fields in same data table - python

This is my models.py file.
class CustomerInfo(models.Model):
customer_name=models.CharField('Customer Name', max_length=50)
customer_mobile_no = models.CharField('Mobile No', null=True, blank=True,max_length=12)
customer_price=models.IntegerField('Customer Price')
customer_product_warrenty = models.CharField('Product Warrenty',null=True, blank=True,max_length=10)
customer_sell_date = models.DateTimeField('date-published', auto_now=True)
customer_product_id=models.CharField('Product ID',max_length=150,null=True, blank=True)
customer_product_name=models.CharField('Product Name', max_length=50)
customer_product_quantity=models.IntegerField('Quantity',default=1)
def __str__(self):
return self.customer_name
Now I want to search in muliple fieds like as customer_name, customer_mobile_no,customer_product_id etc. So I created views.py file
def customerPage(request):
customers = CustomerInfo.objects.all()
if request.method =="GET":
customerid = request.GET['customer_id']
try:
customers = CustomerInfo.objects.get(pk=customerid)
cus_name = CustomerInfo.objects.filter(customer_name__contains=customerid)
mobile_number = CustomerInfo.objects.filter(customer_mobile_no__contains=customerid)
return render(request, 'shop/customer.html', {"cus_name": cus_name,"mobile_number": mobile_number, "customers": 'customers', "site_name": "Moon Telecom"})
except:
return render(request, 'shop/customer.html', {"error": "Not found any info"})
return render(request, 'shop/customer.html', {'customers': customers})
and this is my html file
{% extends "shop/base.html" %}
{% block content_area %}
<div class="col-lg-4">
<div class="customer_search" >
<form action="{% url "shop:customerPage" %}" method="GET">
{% csrf_token %}
<div class="form-group">
<label for="customer_id">Id:</label>
<input type="text" class="form-control" id="customer_id" placeholder="Enter customer ID" name="customer_id">
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
</div>
</div>
<div class="col-lg-8 customers_info">
{% if error %}
<div class="alert alert-danger">
<strong>{{error}}</strong>
</div>
{% endif %}
{% if cus_name %}
{% for x in cus_name %}
<p>{{x.customer_name}}</p>
{% endfor %}
{% else %}
<p>nothing foung</p>
{% endif %}
{% if customers %}
<table class="table">
<thead>
<tr>
<th>Name</th>
<th>Mobile No</th>
<th>Product Name</th>
<th>Price</th>
<th>Date</th>
<th>Product ID</th>
<th>Warrenty</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{customers.customer_name}}</td>
<td>{{customers.customer_mobile_no}}</td>
<td>{{customers.customer_product_name}}</td>
<td>{{customers.customer_price}} TK</td>
<td>{{customers.customer_sell_date}}</td>
<td>{{customers.customer_product_id}}</td>
<td>{% if customers.customer_product_warrenty == '' %}
<b>No Warrenty</b>
{% else %}
<b>{{customers.customer_product_warrenty}}</b> Month
{% endif %}
</td>
</tr>
</tbody>
</table>
{% else %}
<p>nothing found</p>
{% endif %}
</div>
{% endblock %}
I got results If I use POST method and customers = CustomerInfo.objects.get(pk=customerid) When I searched one field, I have got my results but When I start multiple search query from the database. I cant get any info. I want to search multiple fields within CustomerInfo model. Also, I was trying others mehtod but not working.

You need to search using multiple fields in one query. And looking at your code, i presume that the conditions are joined using OR.
This problem can be solved using django ORM's Q object
What it allows you do is to chain multiple filtering conditions together and connect them logically.
So, if you have 3 conditions and they are logically connected as :
Condition 1 OR Condition 2 AND Condition 3 using Q you can write them as :
Q(Condition1) | Q(Conditon2) & Q(Condition2).
In your case the 3 different searches of filterings can be performed as:
filtered_customers = CustomerInfo.objects.filter( Q(pk = int(customerid)) | Q(customer_name__contains = str(customerid)) | Q(customer_mobile_no__contains = str(customerid)))

Related

How can I have a form redirect to same page after submitting in Django?

How can I set my function in views.py so that a form redirects to the same page after submitting?
For example, I want to add time slots:
In my views.py:
#login_required
def post_available_timeslots(request):
print("Check")
if not check_existing_timeslot(request):
print("Time slot does not exist")
instance = TimeSlot()
data = request.POST.copy()
data["time_slot_owner"] = request.user
# data["food_avail_id"] = FoodAvail.objects.get(author=request.user).pk
form = TimeSlotForm(data or None, instance=instance)
if request.POST and form.is_valid():
form.save()
return redirect("food_avail:view_food_avail_res")
else:
print("Time slot does not exist")
messages.info(request, "Time Slot Already Exists")
return render(request, "food_avail/view_food.html", {"time_slot": form})
in models.py
class TimeSlot(models.Model):
time_slot_owner = models.ForeignKey(User, on_delete=models.CASCADE)
# food_avail_id = models.ForeignKey(FoodAvail, on_delete=models.CASCADE)
start_time = models.TimeField()
end_time = models.TimeField()
def __str__(self):
return str(self.start_time) + "-" + str(self.end_time)
In forms.py:
class TimeSlotForm(ModelForm):
class Meta:
model = TimeSlot
fields = ["start_time", "end_time"]
In urls.py:
from django.urls import path
from food_avail import views
app_name = "food_avail"
urlpatterns = [
path("post_food_avail/", views.post_available_food, name="post_food_avail"),
# path("post_food_avail/", views.FoodAvailCreateView.as_view(), name="post_food_avail"),
# path("update_food_avail/", views.post_available_food, name="update_food_avail"),
path("food_avail_all/", views.check_food_availibility, name="view_food_avail"),
path("food_avail_res/", views.view_available_food, name="view_food_avail_res"),
# path("food_avail_res/", views.post_available_timeslots, name="create_timeslots"),
]
in my html template:
{% if form.errors %}
{% for field in form %}
{% for error in field.errors %}
<div class="alert alert-danger">
{{ field.label }} <strong>{{ error|escape }}</strong>
</div>
{% endfor %}
{% endfor %}
{% for error in form.non_field_errors %}
<div class="alert alert-danger">
{{ field.label }} <strong>{{ error|escape }}</strong>
</div>
{% endfor %}
{% endif %}
{% if user.is_authenticated %}
<div>
<div>
<div>
<div>
<h4>
{{ food.author.username }}<br>
</h4>
</div>
<div>
Food Available: {{ food.food_available }}<br>
Description: {{ food.description }}<br>
{% endif %}
</div>
</div>
<div>
<h4>Add Time Slot</h4>
<br><br>
</div>
<div>
<div>
<form method="post">
{{ time_slot.as_p }}
<button type="submit" class="button btn-success">Submit</button>
</form>
</div>
{% if time_slot %}
<h4> List Of Time Slots </h4>
</div>
<div class="card-body">
<div class="table-responsive">
<table class="table table-hover ">
<thead>
<tr>
<th>Start Time</th>
<th>End Time</th>
<th>Edit</th>
<th>Delete</th>
</tr>
</thead>
<tbody>
{% for x in time_slot %}
<tr>
<td>{{x.start_time | time:'H:i:s'}}</td>
<td>{{x.end_time | time:'H:i:s'}}</td>
<td>
{% endfor %}
{% endif %}
I have been stuck on this problem for a minute now so any help would be much appreciated. This is how it currently shows up on my HTML template:

In my django HTML template my text is repeated because of {% for city in cities %} loop

My text in my HTML is repeated because of the {% for %} loop. I already tried to move {% if %} outside of {% for %}. Then my disappears.
This is my html template
{% for city in cities %}
{% if city.author.access_challenge %}
<p class="small text-center"> In order to get information about this contact us through almaz#protonmail.com </p>
{% else %}
<table class="table table-hover text-left col-sm-12" style="table-layout: fixed; word-wrap: break-word;">
<tbody>
<tr>
<td><a class="text-uppercase" href="{% url 'users:address' city.pk %}">{{ city.city }}</a></td>
</tr>
</tbody>
</table>
{% endif %}
{% endfor %}
This is my views.py
def cities(request, pk):
country = Post.objects.get(id=pk).country
cities = Post.objects.filter(country=country).distinct('city')
context = {
'cities':cities,
'country':country
}
return render(request, 'users/cities.html', context)
Also I tried to change my views.py like this:
def cities(request, pk):
country = Post.objects.get(id=pk).country
ci = Post.objects.filter(country=country).distinct('city')
cit = list(ci)
for city in cit:
for cities in cit:
context = {
'cities':cities,
'country':country
}
return render(request, 'users/cities.html', context)
But when I used the for loop, I get an error that Post is not iterable.
When you do
cities = Post.objects.filter(country=country).distinct('city')
What you are tryting to get is list of all distinct cities, but what you get is a queryset of Post objects.
To get list of all distinct cities from you Post model, do:
Post.objects.all().values_list('city').distinct()
Try forloop.first in your code. For e.g. :
Input:
{% for product in products %}
{% if forloop.first == True %}
First time through!
{% else %}
Not the first time.
{% endif %}
{% endfor %}
Output:
First time through!
Not the first time.
Not the first time.
For your case:
{% for city in cities %}
{% if city.author.access_challenge and forloop.first == True %}
<p class="small text-center"> In order to get information about this contact us through almaz#protonmail.com </p>
{% else %}
<table class="table table-hover text-left col-sm-12" style="table-layout: fixed; word-wrap: break-word;">
<tbody>
<tr>
<td><a class="text-uppercase" href="{% url 'users:address' city.pk %}">{{ city.city }}</a></td>
</tr>
</tbody>
</table>
{% endif %}
{% endfor %}
I solved it like this:
my views.py now:
def cities(request, pk):
country = Post.objects.get(id=pk).country
cities = Post.objects.filter(country=country).distinct('city')
author = Post.objects.get(id=pk).author
context = {
'cities':cities,
'country':country,
'author':author,
}
return render(request, 'users/cities.html', context)
my views.py used to be:
def cities(request, pk):
country = Post.objects.get(id=pk).country
cities = Post.objects.filter(country=country).distinct('city')
context = {
'cities':cities,
'country':country
}
return render(request, 'users/cities.html', context)
Before with same code my HTML had error. But now it's working without any errors:
{% if author.access_challenge %}
<p class="text-center col-sm-12"> In order to get info about this country contact <strong>emeupci#protonmail.com</strong></p>
{% else %}
{% for city in cities %}
<table class="table table-hover text-left col-sm-12" style="table-layout: fixed; word-wrap: break-word;">
<tbody>
<tr>
<td><a class="text-uppercase" href="{% url 'users:address' city.pk %}">{{ city.city }}</a></td>
</tr>
</tbody>
</table>
{% endfor %}
{% endif %}

Unable to display the image through the result of CRUD operations in django

i am working on hotel booking app , in this i want to display the image of a hotel, based on user entered location . In this if i am displaying all hotels , i am able to display an image , if i am trying to displaying an image through some CRUD operations, i am unable to display it. Here are my code snippets.
class Customer_details(models.Model):
Name = models.CharField(max_length=128)
Age = models.IntegerField()
Mobile_number = models.IntegerField()
Email = models.EmailField()
Address = models.CharField(max_length=50)
Special_request = models.CharField(max_length=50, blank=True)
user = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self):
return self.Name
hotel_rating_choices = (
('1','1'),
('2','2'),
('3','3'),
('4','4'),
('5','5'),
('6','6'),
('7','7'),
)
class Hotel(models.Model):
Hotel_Name = models.CharField(max_length=50)
location = models.CharField(max_length=20)
no_of_rooms = models.IntegerField()
rating = models.CharField(max_length=1, choices=hotel_rating_choices, default=3)
hotel_img = models.ImageField(upload_to='hotel_images/')
uploaded_at = models.DateTimeField(auto_now_add=True)
user = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self):
return self.Hotel_Name
class Hotel_image(models.Model):
hotel_img = models.ImageField(upload_to = 'hotel_images/')
hotel = models.ForeignKey(Hotel, on_delete=models.CASCADE)
def __str__(self):
return self.hotel
Ignore the remaining models just concentrate on Hotel model .
`Below code snippet is my view regarding to query.
def get_hotels_by_location(request):
location = request.POST.get('location')
print(location)
location = location.lower()
result = Hotel.objects.values('Hotel_Name', 'rating', 'hotel_img').filter(location=location)
context = {'hotels': result, 'header': ['Hotel_Name', 'Rating', 'image'] }
return render(
request,
template_name='display_hotel_by_location.html',
context=context
)
And below is my django html template
<table class="table">
<tr>
{% for i in header %}
<th>
{{ i }}
</th>
{% endfor %}
</tr>
{% for element in hotels %}
<tr>
{% with i=0 %}
{% for key, value in element.items %}
{% if i == 2 %}
<td> <img src="{{ element.url }}" width = "300" height="300"> </td>
{% endif %}
<td> {{ value }} </td>
{% with j=i %}
j=j+1
i=j
{% endwith %}
{% endfor %}
</tr>
{% endfor %}
</table>
Please help me on this issue.
Change your Hotel_image class to add related name at your foreign to use it further
class Hotel_image(models.Model):
hotel_img = models.ImageField(upload_to = 'hotel_images/')
hotel = models.ForeignKey(Hotel, on_delete=models.CASCADE, related_name="hotel_images")
Clean up a bit your views, you dont really need use values in that case.
from .models import Hotel
def get_hotels_by_location(request):
location = request.POST.get('location').lower()
result = Hotel.objects.filter(location=location)
context = {'hotels': result, 'header': ['Hotel_Name', 'Rating', 'image'] }
return render(
request,
template_name='display_hotel_by_location.html',
context=context
)
HTML 1 - If you consuming the hotel_img from class Hotel use this one
<table class="table">
<tr>
{% for i in header %}
<th>{{ i }}</th>
{% endfor %}
</tr>
{% for hotel in hotels %}
<tr>
{% if forloop.counter0 == 2 and hotel.hotel_img %}
<td> <img src="{{ hotel.hotel_img.url }}" width="300" height="300"> </td>
{% endif %}
<td> {{ hotel.Hotel_Name }} </td>
</tr>
{% endfor %}
</table>
HTML 2 - If you using the class Hotel_image use like that
<table class="table">
<tr>
{% for i in header %}
<th>{{ i }}</th>
{% endfor %}
</tr>
{% for hotel in hotels %}
<tr>
{% for img in hotel.hotel_images %}
{% if img.hotel_img %}
<td> <img src="{{ img.hotel_img.url }}" width="300" height="300"> </td>
{% endif %}
{% endfor %}
<td> {{ hotel.Hotel_Name }} </td>
</tr>
{% endfor %}
</table>
More info about Django relations: https://docs.djangoproject.com/en/2.0/ref/models/fields/#django.db.models.ForeignKey.related_name
You can use Template Tags too to filter all images from your Hotel_Image
1 - Create one folder called templatetag and inside that one file inside it to be your templatetag inside your app folder
hotel/templatetags/hotel_templatetag.py
Inside the file put that code
from django import template
from .models import Hotel_image
register = template.Library()
def get_hotel_images(self):
return Hotel_image.objects.filter(id=self.id)
You Html should be like that
<table class="table">
<tr>
{% for i in header %}
<th>{{ i }}</th>
{% endfor %}
</tr>
{% for hotel in hotels %}
<tr>
{% for img in hotel|get_hotel_images %}
{% if img.hotel_img %}
<td> <img src="{{ img.hotel_img.url }}" width="300" height="300"> </td>
{% endif %}
{% endfor %}
<td> {{ hotel.Hotel_Name }} </td>
</tr>
{% endfor %}
</table>
More info about templatetags: https://docs.djangoproject.com/en/2.0/howto/custom-template-tags/

django multiple search terms

I want to add all the columns in 1 algorithm for a search. If it is possible.
Something like this:
*UPDATE * ( i have update the views.py and search_table.html )
It is only searching correctly the url field. The id and the title anything i put in those fields it will give me the entire table.
views.py
def search_table(request, pk):
table_name = Crawledtables.objects.get(id=pk)
t = create_model(table_name.name)
q = request.GET['q']
if q is not None:
query = t.objects.filter(Q(id__icontains=q) | Q(title__icontains=q) | Q(url__icontains=q))
return render(request, 'search/results_table.html', {'tbl_name': table_name,
'details': query,
'query': q})
else:
return HttpResponse("Please submit a search term!")
results_table.html
<strong> {{ tbl_name }}</strong>
<p> You searched for: <strong>{{ query }}</strong></p>
{% if details %}
<p> Found {{ details|length }}</p>
<div class="row">
<table class="table table-bordered sortable">
<thead>
<tr>
<th>Id</th>
<th>Title</th>
<th>Url</th>
</tr>
</thead>
<tbody>
{% for lists in details %}
<tr>
<td>{{ lists.id }}</td>
<td>{{ lists.title }}</td>
<td>{{ lists.url }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% else %}
<p> No results found</p>
{% endif %}
{% endblock %}
search_table.html
{% if tbl_name %}
<form action="/search/{{ tbl_name.id }}/results" method="GET">
{% endif %}
<input type="text" name="q" placeholder="Id">
<input type="text" name="q" placeholder="Title">
<input type="text" name="q" placeholder="Url">
<input type="submit" value="Search">
</form>
UPDATE
models.py
def create_model(db_table):
class CustomMetaClass(ModelBase):
def __new__(cls, name, bases, attrs):
model = super(CustomMetaClass, cls).__new__(cls, name, bases, attrs)
model._meta.db_table = db_table
return model
class AllTables(models.Model):
__metaclass__ = CustomMetaClass
id = models.IntegerField(primary_key=True)
title = models.CharField(db_column='Title', blank=True, null=True, max_length=250)
url = models.CharField(db_column='Url', unique=True, max_length=250, blank=True,
null=True)
created_at = models.DateTimeField(db_column='Created_at')
return AllTables
Q objects are used to make complex logical queries.
use in syntax: AND (&) and OR (|)
from django.db.models import Q
t.objects.filter(Q(id__icontains=q_id) | Q(title__icontains=q_title) | Q(url__icontains=q_url))

Django invalid literal for int() with base 10: 'Stalone'

I'm trying to get the users that I'm marking as True on my website in data['checked_users']:
models.py
class Player(models.Model):
jucator = models.ForeignKey(settings.AUTH_USER_MODEL, default=1, related_name='jucator')
porecla = models.CharField(max_length=50, null=True, blank=True)
selectat = models.BooleanField(default=False)
def __str__(self):
return u'%s' % self.jucator
views.py
def check_user(request):
data = dict()
data['players'] = Player.objects.all()
if request.method == 'POST':
list_of_checks = request.POST.getlist('checks[]')
# data['checked_users'] = list_of_checks
data['checked_users'] = Player.objects.filter(jucator__in=list_of_checks)
return render(request, 'checkbox.html', data)
checkbox.html
<body>
{% block content %}
<form action="" method="POST">{% csrf_token %}
<table>
{% if request.user.is_superuser %}
{% for user in players %}
<tr>
<td><input type="checkbox" name="checks[]" value="{{ user.jucator }}" title="selected_players">{{ user.jucator }}<br></td>
</tr>
{% endfor %}
<tr>
<td><input type="submit" name="submit" value="Submit"></td>
</tr>
{% else %}
{% for user in players %}
<tr><td>{{ user.jucator }}</td></tr>
{% endfor %}
{% endif %}
</table>
{% for player in checked_users %}
{{ player }}
{% endfor %}
</form>
{% endblock %}
</body>
If I try this, it shows the players:
data['checked_users'] = list_of_checks
If I try with filter, I get this error:
invalid literal for int() with base 10: 'Stalone'
You need to put inside value="{{ user.jucator }}" the actual id of the jucator object. Not the jucator object itself.
So, change to this: value="{{ user.jucator.id }}". Now you can query with Player.objects.filter(jucator__in=list_of_checks) since list_of_checks containts a list of integers (the ids of jucators).

Categories