django multiple search terms - python

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))

Related

Why my searching by multiple categories in Django has not result?

Hi everyone! I want search by multiple categories, but my code is not working. When I type categories name, I got nothing. Can anyone help me?
'''views.py'''
class ExpenseListView(ListView):
model = Expense
paginate_by = 5
def get_context_data(self, *, object_list=None, **kwargs):
queryset = object_list if object_list is not None else self.object_list
form = ExpenseSearchForm(self.request.GET)
if form.is_valid():
name = form.cleaned_data.get('name', '').strip()
if name:
queryset = queryset.filter(name__icontains=name)
return super().get_context_data(
form=form,
object_list=queryset,
summary_per_category=summary_per_category(queryset),
get_per_year_month_summary=get_per_year_month_summary(queryset),
**kwargs)
def get_queryset(self):
queryset = super(ExpenseListView, self).get_queryset()
q = self.request.GET.get("q")
if q:
return queryset.filter(date__icontains=q)
return queryset
def get_gategory(request, pk_test):
category = Category.objects.get(id=pk_test)
orders = category.order_set.all()
order_count = orders.count()
myFilter = OrderFilter(request.GET, queryset=orders)
orders = myFilter.qs
context = {'category': category, 'orders': orders,
'order_count': order_count, 'myFilter': myFilter }
return render(request, 'expense_list.html',context)
'''May be my problem is in my vieews or in models. I m new in Django and dont nkow many things..'''
''' Here my models.py'''
class Category(models.Model):
class Meta:
ordering = ('name',)
name = models.CharField(max_length=50, unique=True)
def __str__(self):
return f'{self.name}'
class Expense(models.Model):
class Meta:
ordering = ('-date', '-pk')
category = models.ForeignKey(Category, models.PROTECT, null=True, blank=True)
name = models.CharField(max_length=50)
amount = models.DecimalField(max_digits=8, decimal_places=2)
date = models.DateField(default=datetime.date.today, db_index=True)
def __str__(self):
return f'{self.date} {self.name} {self.amount}'
'''html''
{% extends "base.html" %}
{% block content %}
add
<form method="get">
{{form.as_p}}
<button type="submit">search</button>
</form>
<hr>
{% if expenses %}
<form action="#" method="GET">
{% endif %}
<input type="text" name="q" placeholder="category">
<input type="text" name="q" placeholder="name">
<input type="submit" value="Search">
</form>
<hr>
<form method="GET" action={% url 'expenses:expense-list' %}>
{% csrf_token %}
From: <input type="date" name="q"/>
To: <input type="date" name="q"/>
From_category:
<select>
<option selected disabled="true"></option>
{% for obj in object_list %}
<option value="{{ obj.category }}">{{obj.category}}</option>
{%endfor%}
</select>
<button type="submit">search</button>
</form>
</div>
<br>
<table border="1">
<caption>Expenses</caption>
<thead>
<tr>
<th>no.</th>
<th>category</th>
<th>name</th>
<th>amount</th>
<th>date</th>
<th>actions</th>
</tr>
</thead>
<tbody>
{% for obj in object_list %}
<tr>
<td>{{ page_obj.start_index|add:forloop.counter0 }}.</td>
<td>{{ obj.category|default:"-" }}</td>
<td>{{ obj.name|default:"-" }}</td>
<td>{{ obj.amount|floatformat:2 }}</td>
<td>{{obj.date}}</td>
<td>
edit
delete
</td>
</tr>
{% empty %}
<tr>
<td colspan="5">no items</td>
</tr>
{% endfor %}
</tbody>
</table>
</form>
{% include "_pagination.html" %}
<hr>
<table border="1">
<caption>Summary per category</caption>
<tr>
{% for category, total in summary_per_category.items %}
<tr>
<td>{{category}}:</td>
<td>{{total|floatformat:2}}</td>
</tr>
{% endfor %}
</tr>
</table>
<hr>
<table border="2">
<caption>Summary per year-month </caption>
<tr>
{% for year, total_year in get_per_year_month_summary.items %}
<tr>
<td>{{year}}</td>
<td>{{total_year|floatformat:2}}</td>
</tr>
{% endfor %}
</tr>
</table>
{% endblock %}
'''urls'''
urlpatterns = [
path('expense/list/',
ExpenseListView.as_view(),
name='expense-list'),
path('expense/create/',
CreateView.as_view(
model=Expense,
fields='__all__',
success_url=reverse_lazy('expenses:expense-list'),
template_name='generic_update.html'
),
name='expense-create'),
path('expense/<int:pk>/edit/',
UpdateView.as_view(
model=Expense,
fields='__all__',
success_url=reverse_lazy('expenses:expense-list'),
template_name='generic_update.html'
),
name='expense-edit'),
path('expense/<int:pk>/delete/',
DeleteView.as_view(
model=Expense,
success_url=reverse_lazy('expenses:expense-list'),
template_name='generic_delete.html'
),
name='expense-delete'),
path('category/list/',
CategoryListView.as_view(),
name='category-list'),
path('category/create/',
CreateView.as_view(
model=Category,
fields='__all__',
success_url=reverse_lazy('expenses:category-list'),
template_name='generic_update.html'
),
name='category-create'),
path('category/<int:pk>/delete/',
DeleteView.as_view(
model=Category,
success_url=reverse_lazy('expenses:category-list'),
template_name='generic_delete.html'
),
name='category-delete'),
path('category/<int:pk>/update/',
UpdateView.as_view(
model=Category,
fields='__all__',
success_url=reverse_lazy('expenses:category-list'),
template_name='generic_update.html'
),
name='category-update'),
]
this is screen of my projects views

Add multiple products to an order - Django

I'm trying to create an inventory management system. I'm having problems figuring out how to add multiple inventory items into my order from a table. I want to achieve this by selecting the item by the checkbox and also adding the quantity. I also eventually want to add a search bar to search through the table
html
<form method="POST" action="">
{% csrf_token %}
{% for field in form %}
<div class="form-group row">
<Label for="id_{{ field.name }}" class="col-2 col-form-label">{{ field.label }}</Label>
<div class="col-10">
{{ field }}
</div>
</div>
{% endfor %}
<table class="table table-striped">
<tbody>
{% for item in Inventory %}
<tr>
<td> <input type="checkbox" name="itemCheck" value="{{ item.pk }} "></td>
<td> <input name="itemQuantity"> </td>
<td> {{ item.name }} </td>
<td> {{ item.quantity }} </td>
<td> <span class="badge badge-pill badge-success">{{item.status}}</span></td>
<td> ${{ item.sale_price }} </td>
</td>
</tr>
{% endfor %}
</tbody>
</table>
views.py
def create_order(request):
order_form = OrderForm(request.POST)
if request.method == 'POST':
if formset.is_valid():
total = 0
order = Orders(total=total)
order.save()
order_form.save()
selected_items = request.POST.getlist('itemCheck')
print(selected_items) # This returns the primary keys of the selected items
context = {"form": order_form, "Inventory": Inventory.objects.all()}
return render(request, 'create_order.html', context)
models
class Inventory(models.Model):
name = models.CharField(max_length=128, blank=False)
...
def __str__(self):
return f"{self.id} - {self.name}"
class Orders(models.Model):
studio = models.CharField(max_length=64)
status = models.CharField(max_length=64, default="warehouse", blank=False)
total = models.DecimalField(max_digits=10, decimal_places=2)
class OrderEquipment(models.Model):
equipment = models.ForeignKey(Inventory, blank=False, on_delete=models.CASCADE)
order = models.ForeignKey(Orders, on_delete=models.CASCADE)
quantity = models.IntegerField(blank=False)
For the sake of simplicity, since you didn't post your formset and other code, I'm going to assume your HTML and formset are coming in correctly and just focus on the table/model loading. I have found the best way to load many items is to use bulk_create(). You may need to fidget around with the below code, but it should get you on the right track.
from django.db import transaction
try:
with transaction.atomic():
# I put cleaned_data below. You need to replace with your Orders data if different.
order = Orders.objects.create(**cleaned_data)
# Loop thru OrderEquipment Items. I'm guessing your 'selected_items' is the inventory data, (equipment and quantity).
orderequip_list = []
for equip in selected_items:
orderequip_list.append(OrderEquipment(order=order, **equip))
OrderEquipment.objects.bulk_create(orderequip_list)
except (IntegrityError, ObjectDoesNotExist):
order = None

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 Inline Formset - possible to follow foreign key relationship backwards?

I'm pretty new to django so I apologize if this has an obvious answer.
Say you have the following three models:
models.py
class Customer(models.Model):
name = models.CharField()
slug = models.SlugField()
class Product(models.Model):
plu = models.Charfield()
description = models.Charfield()
class Template(models.Model):
customer = models.ForeignKey(Customer)
product = models.ForeignKey(Product)
price = models.DecimalField()
The inline formset would look something like:
TemplateFormSet = inlineformset_factory(Customer, Template, extra=0,
fk_name='customer', fields=('price'))
Is it possible to follow the Template formset's Product foreign key backwards so you could display the plu and description fields within the same table?
For example something like this:
<table>
<tbody>
{% for obj in customer.template_set.all %}
<tr>
<td>{{ obj.product.plu }}</td>
<td>{{ obj.product.description }}</td>
<td>{% render_field formset.form.price class="form-control form-control-sm" %}</td>
</tr>
{% endfor %}
</tbody>
</table>
The formset's fields appear with the html above but the data from the bound form instance doesn't appear and I can't save by editing the empty fields.
I've also tried below but each formset is repeated for each object (for x formsets there are x*x rows):
<tbody>
{% for obj in customer.template_set.all %}
{% for form in formset %}
<tr>
<td>{{ obj.product.plu }}</td>
<td>{{ obj.product.description }}</td>
<td>{% render_field form.price class="form-control" %}</td>
</tr>
{% endfor %}
{% endfor %}
</tbody>
Basically I'm trying to go from the top portion of the image to the bottom
The formset functionality is only to show forms but something that you can do is create a custom form that display the 2 fields with the function of readonly like:
class your_form(models.ModelForm):
class Meta()
model = Template
fields = ['price', 'product']
def __init__(self, *args, **kwargs):
super(ItemForm, self).__init__(*args, **kwargs)
self.fields['product'].widget.attrs['readonly'] = True
TemplateFormSet = inlineformset_factory(Customer, Template, extra=0,
fk_name='customer', form=your_form)
That's my best tried, if you wanna display both try returning in your models something like:
class Product(models.Model):
plu = models.Charfield()
description = models.Charfield()
def __str__(self, *args, **kwargs):
a = '<td>' + self.plu + '</td><td>' + self.plu '</td>'
return self.plu + self.description # Or return 'a'
I managed to get it working although I'm not sure its the most efficient way. If anyone has a better way please let me know.
{{ formset.management_form }}
<table>
<thead>
...
</thead>
<body>
{% for obj in customer.template_set.all %}
{% with forloop.counter as outer_counter %}
{% for form in formset %}
{% if forloop.revcounter == outer_counter %}
{% for hidden in form.hidden_fields %} {{ hidden }} {% endfor %}
<tr>
<td>{{ obj.product.plu }}</td>
<td>{{ obj.product.description }}</td>
<td>{% render_field form.price class="form-control" %}</td>
</tr>
{% endif %}
{% endfor %}
{% endwith %}
{% endfor %}
</tbody>
</table>
Should also mention I'm using django-widget-tweaks which is where {% render_field %} comes from.
Update (the proper way):
{% for template in customer.template_set.all %}
{% for form in formset %}
{% if form.instance.id == template.pk %}

Django Search query within multiple fields in same data table

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)))

Categories