Using django searchvector returns duplicate objects - python

I have this code:
vector = SearchVector('product__name', weight='A') + SearchVector('product__tags__name', weight='B')
logger.info("busqueda libre, query %s" % query)
data = StockItem.objects.annotate(search=vector).filter(search=query, product__cover__isnull=False,
available=True).order_by(sort)
And return duplicates objects in the query, i can't use distinct because the order is give by the user, so what i can use for fix this problem?
Models uses in the query:
class StockItem(models.Model):
product = models.ForeignKey(Product, null=False, related_name='items', on_delete=models.CASCADE, db_index=True)
available = models.BooleanField(default=True)
retailer = models.ForeignKey(Retailer, null=False, related_name='items', db_index=True)
sku = models.CharField(max_length=100, db_index=True, unique=True)
price = models.DecimalField(decimal_places=2, null=True, max_digits=6, blank=True)
cost_price = models.DecimalField(decimal_places=2, null=True, max_digits=6, blank=True)
promo = models.ForeignKey(PromoItem, null=True, blank=True)
updated_at = models.DateTimeField(auto_now=True, db_index=True)
margin = models.DecimalField(decimal_places=2, max_digits=4, null=True, blank=True)
class Product(models.Model):
UNITS = (
('LB', _(u'lb')),
('KG', _(u'kg')),
('G', _(u'g')),
('ML', _(u'ml')),
('L', _(u'l')),
('U', _(u'un')),
('ATADO', _(u'atado'))
)
name = models.CharField(max_length=100, db_index=True)
ean = models.CharField(max_length=13, db_index=True, unique=True)
quantity = models.DecimalField(null=True, decimal_places=2, max_digits=10)
unit = models.CharField(max_length=6, choices=UNITS, null=True, db_index=True)
likes = models.PositiveSmallIntegerField(default=0)
brand = models.ForeignKey(Brand, null=True, blank=True, related_name='products', db_index=True)
tags = models.ManyToManyField(Tag, blank=True, db_index=True)
category = models.ManyToManyField(Category, blank=True, related_name='products_category', db_index=True)
subcategory = models.ManyToManyField(SubCategory, blank=True, related_name='products_subcategory')
tax = models.ManyToManyField(Tax, related_name="taxes", blank=True)
description = HTMLField(blank=True, null=True, max_length=15000)
updated_at = models.DateTimeField(auto_now=True, db_index=True)
bulk = models.BooleanField(default=False)
unit_stock = models.BooleanField(default=False)
class Tag(models.Model):
name = models.CharField(max_length=100, db_index=True)

Related

def __str__(self): return str(self.name) in model

Here is my models.py. def str(self):return str(self.name) still won't change Product object (1) to the product name.
from cgi import print_exception
from django.db import models
from django.contrib.auth.models import User
# Create your models here.
class Product(models.Model):
user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
name = models.CharField(max_length=200, null=True, blank=True)
# image =
category = models.CharField(max_length=200, null=True, blank=True)
description = models.TextField(null=True, blank=True)
rating = models.DecimalField(
max_digits=7, decimal_places=2, null=True, blank=True)
numReviews = models.IntegerField(null=True, blank=True, default=0)
price = models.DecimalField(
max_digits=7, decimal_places=2, null=True, blank=True)
countInStock = models.IntegerField(null=True, blank=True, default=0)
createdAt = models.DateTimeField(auto_now_add=True)
_id = models.AutoField(primary_key=True, editable=False)
def __str__(self):
return str(self.name)
You should define __str__() method inside the class, also use f strings so:
class Product(models.Model):
user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
name = models.CharField(max_length=200, null=True, blank=True)
# image =
category = models.CharField(max_length=200, null=True, blank=True)
description = models.TextField(null=True, blank=True)
rating = models.DecimalField(
max_digits=7, decimal_places=2, null=True, blank=True)
numReviews = models.IntegerField(null=True, blank=True, default=0)
price = models.DecimalField(
max_digits=7, decimal_places=2, null=True, blank=True)
countInStock = models.IntegerField(null=True, blank=True, default=0)
createdAt = models.DateTimeField(auto_now_add=True)
_id = models.AutoField(primary_key=True, editable=False)
def __str__(self):
return f"{self.name}"
if your __str__ not work and you receive a Object (1), it mean you use repr(obj). Therefore you should override __repr__ method.
def __repr__(self):
return f'{self.name}'

How do I attach the user's order to the product issued Django

Ok, so I have this application where the users make an order for a Category through the app. Every category contains products. And what I want to do is when a product is issued to the user the order status for the order made by the user should change from 1(approved) to 4(issued) and the product name should be added in the order table to confirm the product that was issued to that request.
How do I do that in Django? Below are my models
class Category(models.Model):
name = models.CharField(max_length=50, blank=True, null=True)
timestamp = models.DateTimeField(auto_now_add=False, auto_now=True, null=True)
class Product(models.Model):
pro_name = models.CharField(max_length=100, blank=True, null=True)
category = models.ForeignKey(Category, on_delete=models.CASCADE, blank=True, null=True)
issue_to = models.ForeignKey('Order',default='', on_delete=models.CASCADE,blank=True, null=True)
serial_num = models.CharField(max_length=100, blank=True, null=True)
model_num = models.CharField(max_length=100, blank=True, null=True)
storage_size = models.CharField(max_length=50, blank=True, null=True)
memory_size = models.CharField(max_length=50, blank=True, null=True)
supplier = models.ForeignKey(Supplier, on_delete=models.CASCADE, blank=True, null=True)
receive_quantity = models.IntegerField(default='0', blank=True, null=True)
issue_quantity = models.IntegerField(default='0', blank=True, null=True)
issue_by = models.CharField(max_length=50, blank=True, null=True)
last_updated = models.DateTimeField(auto_now_add=False, auto_now=False, null=True)
timestamp = models.DateTimeField(auto_now_add=False, auto_now=True, null=True)
class Order(models.Model):
category = models.ForeignKey(Category, on_delete=models.CASCADE, null=True)
pro_name = models.ForeignKey(Product, on_delete=models.CASCADE, null=True,related_name='product')
staff = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
order_quantity = models.PositiveIntegerField(null=True)
department = models.CharField(max_length=50, choices=DEPARTMENT, null=True)
order_status = models.IntegerField(default=0)
approve_quantity = models.IntegerField(default='1', blank=True, null=True)
transaction_id = models.CharField(default=uuid.uuid4().hex[:8].upper(), max_length=50, editable=False)
timestamp = models.DateTimeField(auto_now_add=False, auto_now=True, null=True)
Currently what I do is after a particular product has been issued to a user I have to go to the order table and change the order status to 4(issued) which is hectic especially when the orders are plenty.

How to filter product by its Attribute in Django - Django?

I'm working on a Django Ecommerce project where product has several attributes like. size, color( A single product can have multiple attributes with different size and color). No i'm trying to filter products using django_filters but unable to filter by its attributes.
Product Model:
class Product(models.Model):
variations = (
('None', 'None'),
('Size', 'Size'),
)
name = models.CharField(max_length=200, unique=True)
store = models.ManyToManyField(Store)
slug = models.SlugField(null=True, blank=True, unique=True, max_length=500)
sku = models.CharField(max_length=30, null=True)
tax = models.IntegerField(null=True, blank=True)
stock = models.CharField(max_length=10, null=True)
variations = models.CharField(choices=variations, max_length=20)
short_description = models.CharField(max_length=500, null=True)
details = RichTextUploadingField(null=True, blank=True)
price = models.DecimalField(max_digits=10, decimal_places=2)
discounted_price = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True)
image = models.ImageField(upload_to='product/images', default='product.png', null=True,
blank=True)
image_one = models.ImageField(upload_to='product/images', null=True, blank=True)
image_two = models.ImageField(upload_to='product/images', null=True, blank=True)
image_three = models.ImageField(upload_to='product/images', null=True, blank=True)
image_four = models.ImageField(upload_to='product/images', null=True, blank=True)
image_five = models.ImageField(upload_to='product/images', null=True, blank=True)
tags = models.ManyToManyField(Tags)
category = models.ForeignKey(Category, on_delete=models.SET_NULL, null=True, blank=True,
related_name='products')
status = models.CharField(max_length=20, choices=(('Active', 'Active'), ('Inactive',
'Inactive')))
brand = models.ForeignKey(Brand, on_delete=models.PROTECT, blank=True, null=True)
offer = models.ForeignKey(Offer, on_delete=models.CASCADE, null=True,
blank=True) # This is used only for filtration
Product attribute model
class ProductAttribute(models.Model):
product = models.ForeignKey(Product, on_delete=models.CASCADE)
size = models.ForeignKey(Size, on_delete=models.CASCADE, null=True, blank=True)
price = models.DecimalField(max_digits=10, decimal_places=2, validators=
[MinValueValidator(1)])
discounted_price = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True)
stock = models.CharField(max_length=10, null=True)
The standard approach would be to define the attributes in the "Product" model. However, if you insist on doing this, the code will be:
filtered_ProductAttributes=ProductAttribute.objects.filter(size="12")
products=[filtered_ProductAttribute.product for filtered_ProductAttribute in filtered_ProductAttributes]
As you can see the code seems very inefficient, therefore, as was suggested in the beginning put the attributes in the "Product" model and you will have:
products=Product.objects.filter(size="12")
Refining your model will help you to filter.
With my experience following model approach will be more suitable:
class Attributes(models.Model):
name = models.CharField(max_length=50, default=None)
slug = models.SlugField(max_length=200, unique=True,null=True)
class AttributeTerms(models.Model):
name = models.CharField(max_length=50, blank =True)
attribute = models.ForeignKey(Attributes, on_delete=models.CASCADE)
class Products(models.Model):
name = models.CharField(max_length=250,null=True, blank=True,)
slug = models.SlugField(max_length=200, unique=True,null=True)
class ProductAttribute(models.Model):
product = models.ForeignKey(Products,on_delete=models.CASCADE, related_name='attributes', default=None)
attributes = models.ForeignKey(Attributes,on_delete=models.CASCADE, related_name='attributes', default=None)
values = models.ForeignKey(AttributeTerms, on_delete=models.CASCADE, related_name='attributes', default=None)
class ProductVariant(models.Model):
product = models.ForeignKey(Products,on_delete=models.CASCADE)
variant = models.ForeignKey(ProductAttribute,on_delete=models.CASCADE, null = True, default=None)
stock = models.IntegerField(default=None)
stock_threshold = models.IntegerField()
price = models.DecimalField(max_digits=10, decimal_places=2)
sku = models.CharField(max_length= 250, default=None)
sale_price = models.DecimalField(max_digits=10, decimal_places=2)

Django: How do i extract the email ID of users on the admin page

How do I extract the email ID of users from the Users columns? I've managed to make sure that the name of the users are extracted through the Users table.
class Project(models.Model):
STATUS_CHOICE = (
('Project Manager', 'Project Manager'),
('Technician', 'Technician'),
('Tester', 'Tester')
)
STATUS_CHOICE_1 = (
('Work Assigned', 'Work Assigned'),
('Work in Progress', 'Work in Progress'),
('Testing', 'Testing'),
('Completed', 'Completed')
)
project_name = models.CharField(max_length=100)
project_description = models.CharField(max_length=100)
Admin_Name = models.CharField(max_length=100)
Admin_Mail_ID = models.EmailField(max_length=50)
Project_Manager_1 = models.ForeignKey(User, on_delete=models.CASCADE, related_name="Project_Manager_1_users")
Project_Manager_1_Mail_ID = models.EmailField(max_length=50)
Project_Manager_2 = models.CharField(max_length=50, blank=True, null=True)
Project_Manager_2_Mail_ID = models.EmailField(max_length=50, blank=True, null=True)
Technician_1 = models.ForeignKey(User, on_delete=models.CASCADE, related_name="Technician_1_users")
Technician_1_Mail_ID = models.EmailField(max_length=50)
Technician_2 = models.CharField(max_length=50, blank=True, null=True)
Technician_2_Mail_ID = models.EmailField(max_length=50, blank=True, null=True)
Technician_3 = models.CharField(max_length=50, blank=True, null=True)
Technician_3_Mail_ID = models.EmailField(max_length=50, blank=True, null=True)
Tester_1 = models.CharField(max_length=50, blank=True, null=True)
Tester_1_Mail_ID = models.EmailField(max_length=50, default='Example#gmail.com')
Additional_User_1 = models.CharField(max_length=50, blank=True, null=True)
Additional_User_1_Type = models.CharField(max_length=18, choices=STATUS_CHOICE, blank=True, null=True)
Additional_User_1_Mail_ID = models.EmailField(max_length=50, blank=True, null=True)
Additional_User_2 = models.CharField(max_length=18, blank=True, null=True)
Additional_User_2_Type = models.CharField(max_length=18, choices=STATUS_CHOICE, blank=True, null=True)
Additional_User_2_Mail_ID = models.EmailField(max_length=50, blank=True, null=True)
Additional_User_3 = models.CharField(max_length=18, blank=True, null=True)
Additional_User_3_Type = models.CharField(max_length=18, choices=STATUS_CHOICE, blank=True, null=True)
Additional_User_3_Mail_ID = models.EmailField(max_length=50, blank=True, null=True)
Status_of_the_project = models.CharField(max_length=18, choices=STATUS_CHOICE_1)
Created = models.DateTimeField(auto_now_add=True, null=True, blank=True)
Finish_Date = models.DateTimeField(null=True, blank=True)
Supporting_Documents = models.FileField(null=True, blank=True)
I'm not that great at coding and I would really appreciate all the help I'd get.. Thank you so much everyone..

Django join multiple models using django ORM

I googled and read many articles but got confused in multiple table join.
My models looks like-
class ProductCategory(models.Model):
category_name = models.CharField(max_length=200,blank=True, null=True, unique=True)
category_image = models.ImageField(upload_to='category', null=True, blank=True)
created_at = models.DateTimeField(auto_now_add=True, blank=True, null=True)
updated_at = models.DateTimeField(auto_now=True, blank=True, null=True)
status = models.CharField(max_length=10, default='Active', choices=status)
def __unicode__(self):
return '%s' % ( self.category_name)
class ProductSubCategory(models.Model):
category = models.ForeignKey(ProductCategory)
sub_category_name = models.CharField(max_length=200,blank=True, null=True, unique=True)
created_at = models.DateTimeField(auto_now_add=True, blank=True, null=True)
updated_at = models.DateTimeField(auto_now=True, blank=True, null=True)
sub_category_image = models.ImageField(upload_to='subcategory', null=True, blank=True)
status = models.CharField(max_length=10, default='Active', choices=status)
def __unicode__(self):
return '%s' % ( self.sub_category_name)
class Product(models.Model):
category = models.ForeignKey(ProductCategory)
sub_category = models.ForeignKey(ProductSubCategory)
product_name = models.CharField(max_length=200,blank=True, null=True)
product_price = models.FloatField(default=0)
created_at = models.DateTimeField(auto_now_add=True, blank=True, null=True)
updated_at = models.DateTimeField(auto_now=True, blank=True, null=True)
# is_discountable = models.CharField(max_length=3, default='Yes', choices=option)
status = models.CharField(max_length=10, default='Active', choices=status)
def __unicode__(self):
return '%s' % ( self.product_name)
class ProductColor(models.Model):
product = models.ForeignKey(Product)
product_color = models.ForeignKey(Color, related_name='product_color_id', blank=True, null=True)
product_size = models.ForeignKey(Size, related_name='product_size_id', blank=True, null=True)
class ProductImages(models.Model):
product = models.ForeignKey(Product, on_delete=models.CASCADE, blank=True, null=True)
product_image = models.ImageField(upload_to='images', null=True, blank=True)
Now in views, I want to get the product filters according to category and sub-category having all the images and colors. Query is something like-
SELECT product.*, productcolor.*, productimage.* FROM product
LEFT JOIN productcolor ON productcolor.product_id = product.id
LEFT JOIN productcolor.product_id = product.id
LEFT JOIN productimage ON productimage.product_id = product.id
WHERE product.category_id=1 and product.sub_category_id=1
Accordingly to your SQL, this will do.
Product.objects.filter(category=<category>, sub_category=<sub_category>) \
.prefetch_related('productcolor_set', 'productimages_set')
This query will prefetch all (with .prefetch_related()) ProductColor and ProductImages related to Product that have your <category> and <sub_category>, they would be stored in productcolor_set and productimages_set respectively.
Also i would suggest to rename your ProductImages model to ProductImage because it represents only one product image.
ProductCategory.productsubcategory_set.all()

Categories