Django queryset foreign key 3 tables - python

I have the following models:
class Productos(models.Model):
nombre = models.CharField(max_length=200, null=True)
precio_publico = models.FloatField(null=True, blank=True)
costo = models.FloatField(null=False, blank=False)
inventario = models.IntegerField(null=False, blank=False, default=0)
fecha_compra = models.DateField(blank=True, null=True)
tipo_movimiento = models.CharField(max_length=1, choices=TIPO_MOVIMIENTO)
slug = models.SlugField(blank=True, null=True)
descripcion_corta = models.TextField(blank=True, null=True)
descripcion = models.TextField(blank=True, null=True)
imagen = models.ImageField(upload_to='images/',blank=True, null=True)
marca = models.CharField(max_length=20)
categoria = models.ForeignKey(Categorias, null= True, on_delete=SET_NULL)
descuento = models.ForeignKey(Promos, blank=True, null=True, on_delete=CASCADE)
inventariar = models.BooleanField(default=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class ProductosOrden(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL,
on_delete=models.CASCADE)
producto = models.ForeignKey(Productos, on_delete=models.CASCADE)
cantidad = models.IntegerField(default=1)
ordenado = models.BooleanField(default=False)
class Orden(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL,
on_delete=models.CASCADE)
producto = models.ManyToManyField(
ProductosOrden)
medio_de_venta = models.ForeignKey(MediosVenta, null=True, blank=False, on_delete=models.SET_NULL)
fecha_venta = models.DateField(blank=False, null=False)
ordenado = models.BooleanField(default=False)
ref_code = models.CharField(max_length=20, blank=True, null=True)
promo = models.ForeignKey(Promos,null=True, blank=True, on_delete=CASCADE )
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
vendido_por = models.CharField(max_length=20, null=False, blank=False)
I need to query from Orden all the way to Productos and get the 'name' attribute
I have tried the following:
categoria = Orden.objects.filter(user=self.request.user, ref_code = '225v3cwhvqi0ymp2yw2n').values('producto__producto')
and I get Id's instead of 'nombre':
<QuerySet [{'producto__producto': 5}, {'producto__producto': 19}, {'producto__producto': 3}]>
how can I access the attribute 'nombre' from the 'Productos' Model?

You should build query like this categoria = Orden.objects.filter(user=self.request.user, ref_code = '225v3cwhvqi0ymp2yw2n').values('producto__producto__nombre')

Related

Django: Join Two Models without ForeignKey: (Can i Use Polymorphic Relation, if Yes Then How)

class Services(models.Model):
id = models.BigAutoField(primary_key=True)
medical_unit = models.ForeignKey(MedicalUnits, models.DO_NOTHING, related_name='services_medical_unit',
blank=True, null=True)
created_at = models.DateTimeField()
updated_at = models.DateTimeField()
name = models.CharField(max_length=500, blank=True, null=True)
billing_code = models.CharField(max_length=500, blank=True, null=True)
department_id = models.IntegerField(blank=True, null=True)
assignable_type = models.CharField(max_length=500, blank=True, null=True)
assignable_id = models.BigIntegerField(blank=True, null=True)
department_service_id = models.IntegerField(blank=True, null=True)
user_id = models.IntegerField(blank=True, null=True)
is_active = models.BooleanField(blank=True, null=True)
ward_id = models.IntegerField(blank=True, null=True)
class Meta:
managed = False
db_table = 'services'
class PackageServices(models.Model):
id = models.BigAutoField(primary_key=True)
billing_package = models.ForeignKey(BillingPackages, models.DO_NOTHING, blank=True, null=True)
assignable_type = models.CharField(max_length=500, blank=True, null=True)
assignable_id = models.BigIntegerField(blank=True, null=True)
quantity = models.IntegerField()
created_at = models.DateTimeField()
updated_at = models.DateTimeField()
class Meta:
managed = False
db_table = 'package_services'
I want To access "PackageService" Through "Services".

Django - Getting an object from an object

I'm trying to get the object "Book" from prommotion. Book is a ForeignKey in "prommotion", and I filtered all the prommotions that are active. I need to get the "Book" object from the Prommotion if its active and return it.
(And I know promotion is spelled wrong)
Views:
class Book_PrommotionViewSet(viewsets.ViewSet):
def list(self, request):
queryset = Prommotion.objects.filter(active=True)
serializer = PrommotionSerializer(queryset, many=True)
return Response(serializer.data, HTTP_200_OK)
Prommotion Model:
class Prommotion(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
precent = models.DecimalField(decimal_places=2, max_digits=255, null=True, blank=True)
active = models.BooleanField(default=False)
date_from = models.DateField()
date_to = models.DateField()
book = models.ForeignKey(Book, on_delete=models.SET_NULL, null=True, blank=True)
country = models.ForeignKey(Country, on_delete=models.SET_NULL, null=True, blank=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
verbose_name = 'Prommotion'
verbose_name_plural = 'Prommotions'
Book Model:
class Book(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
title = models.CharField(max_length=255, null=True, blank=True)
author = models.ForeignKey(Author, on_delete=models.SET_NULL, null=True, blank=True)
price = models.DecimalField(decimal_places=2, max_digits=255)
published = models.DateField()
edition = models.CharField(max_length=255)
isbn_code = models.CharField(max_length=255)
pages = models.IntegerField(blank=True, null=True, default=0)
description = models.TextField(null=True, blank=True)
cover = models.CharField(max_length=30, choices=Cover.choices(), default=None, null=True, blank=True)
genre = models.CharField(max_length=30, choices=Genre.choices(), default=None, null=True, blank=True)
language = models.CharField(max_length=30, choices=Language.choices(), default=None, null=True, blank=True)
format = models.CharField(max_length=30, choices=Format.choices(), default=None, null=True, blank=True)
publisher = models.CharField(max_length=30, choices=Publisher.choices(), default=None, null=True, blank=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return self.title
class Meta:
verbose_name = 'Book'
verbose_name_plural = 'Books'
The first way to get all Books that are related to your active promotions is to extract the book ids from the queryset and pass it to a Book filter
active_promotions = Prommotion.objects.filter(active=True)
Book.objects.filter(id__in=active_promotions.values('book_id'))
Or simply filter books with active promotions by using the double underscore syntax to follow relationships
Book.objects.filter(prommotion__active=True).distinct()

POST 400 Bad Request Django

My branch model has 4 primary keys which are unique together: ('branch_short_name', 'partner_short_name', 'tenant', 'contributor'). I would like to be able to create/ POST some objects with similar
'branch_short_name', 'partner_short_name', 'tenant' but then with a unique 'contributor'.
When doing that I get a 400 bad request error in postman. I don't know where the problem lies, in the model or in the serializer.
models.py
class Branch(models.Model):
additional_address1 = models.CharField(max_length=255, blank=True, null=True)
additional_address2 = models.CharField(max_length=255, blank=True, null=True)
branch_number = models.CharField(max_length=255, blank=True, null=True)
branch_short_name = models.CharField(primary_key=True, max_length=255)
building = models.CharField(max_length=255, blank=True, null=True)
city = models.CharField(max_length=255, blank=True, null=True)
end_date = models.DateTimeField(blank=True, null=True)
country_code = models.CharField(max_length=255, blank=True, null=True)
created = models.DateTimeField(blank=True, null=True)
display_name = models.CharField(max_length=255, blank=True, null=True)
display_web = models.BooleanField(blank=True, null=True)
district = models.CharField(max_length=255, blank=True, null=True)
file_origin_date = models.DateTimeField(blank=True, null=True)
filename = models.CharField(max_length=255, blank=True, null=True)
floor = models.CharField(max_length=255, blank=True, null=True)
business_name = models.CharField(max_length=255, blank=True, null=True)
house_number = models.CharField(max_length=255, blank=True, null=True)
import_file_number = models.BigIntegerField(blank=True, null=True)
contributor = models.CharField(max_length=255)
job_id = models.CharField(max_length=255, blank=True, null=True)
latitude = models.FloatField(blank=True, null=True)
longitude = models.FloatField(blank=True, null=True)
start_date = models.DateTimeField(blank=True, null=True)
branch_hours = models.CharField(max_length=255, blank=True, null=True)
po_box = models.CharField(max_length=255, blank=True, null=True)
province = models.CharField(max_length=255, blank=True, null=True)
region = models.CharField(max_length=255, blank=True, null=True)
remarks = models.CharField(max_length=255, blank=True, null=True)
street = models.CharField(max_length=255, blank=True, null=True)
tenant = models.CharField(max_length=255)
updated = models.DateTimeField(blank=True, null=True)
zip_code = models.CharField(max_length=255, blank=True, null=True)
ranking = models.FloatField()
branch_type = models.IntegerField(blank=True, null=True)
branch_contact_text1 = models.CharField(max_length=255, blank=True, null=True)
branch_contact_text2 = models.CharField(max_length=255, blank=True, null=True)
phone_number = models.CharField(max_length=255, blank=True, null=True)
email_address = models.CharField(max_length=255, blank=True, null=True)
website = models.CharField(max_length=500, blank=True, null=True)
branch_hours_osm = models.CharField(max_length=400, blank=True, null=True)
partner_short_name = models.ForeignKey('Partner', models.DO_NOTHING, db_column='partner_short_name')
features = models.TextField(blank=True, null=True) # This field type is a guess.
marketing_attribute_short_names = models.TextField(blank=True, null=True) # This field type is a guess.
marketing_attribute_values = models.TextField(blank=True, null=True) # This field type is a guess.
class Meta:
managed = False
db_table = 'branch'
unique_together = (('branch_short_name', 'partner_short_name', 'tenant', 'contributor'),)
serializers.py
class BranchSerializer(serializers.ModelSerializer):
class Meta:
model = Branch
fields = '__all__'
views.py
#api_view(['GET', 'POST', 'DELETE'])
def branch_list(request):
# GET list of branchs, POST a new branch, DELETE all branchs
if request.method == 'GET':
branchlist = Branch.objects.all()[:10]
branchlist_serializer = BranchSerializer(branchlist, many=True)
return JsonResponse(branchlist_serializer.data, safe=False)
# 'safe=False' for objects serialization
elif request.method == 'POST':
branch_data = JSONParser().parse(request)
branch_serializer = BranchSerializer(data=branch_data)
if branch_serializer.is_valid():
branch_serializer.save()
return JsonResponse(branch_serializer.data, status=status.HTTP_201_CREATED)
return JsonResponse(branch_serializer.errors, status=status.HTTP_400_BAD_REQUEST)
urls.py
urlpatterns = [
url(r'^api/places$', views.branch_list),
url(r'^api/placescount$', views.branch_count),
url(r'^api/latestimport/(?P<contributor>\D+)$', views.latest_import),
url(r'^api/partners$', views.partner_list),
url(r'^api/partners/(?P<partner_short_name>[0-9]+)$', views.partner_detail),
url(r'^api/places/(?P<branch_short_name>[0-9]+)$', views.branch_detail),
url(r'^api/places/(?P<branch_short_name>[0-9]+)/(?P<contributor>\D+)$' , views.branch_from_contributor),
]

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

Using django searchvector returns duplicate objects

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)

Categories