Django model query - python

I have question about Django query models. I know how to write simple query, but Im not familiar with LEFT JOIN on two tables. So can you give me some advice on his query for better understanding DJango ORM.
query
select
count(ips.category_id_id) as how_many,
ic.name
from
izibizi_category ic
left join
izibizi_product_service ips
on
ips.category_id_id = ic.id
where ic.type_id_id = 1
group by ic.name, ips.category_id_id
From this query I get results:
How many | name
0;"fghjjh"
0;"Papir"
0;"asdasdas"
0;"hhhh"
0;"Boljka"
0;"ako"
0;"asd"
0;"Čokoladne pahuljice"
0;"Mobitel"
2;"Čokolada"
And I have also try with his Django query:
a = Category.objects.all().annotate(Count('id__category',distinct=True)).filter(type_id=1)
But no results.
My models:
models.py
class Category(models.Model):
id = models.AutoField(primary_key=True)
type_id = models.ForeignKey('CategoryType')
name = models.CharField(max_length=255)
def __str__(self):
return str(self.name)
class Product_service(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=255, blank=True, null=True)
selling_price = models.DecimalField(decimal_places=5, max_digits=255, blank=True, null=True)
purchase_price = models.DecimalField(decimal_places=5, max_digits=255, blank=True, null=True)
description = models.CharField(max_length=255, blank=True, null=True)
image = models.FileField(upload_to="/", blank=True, null=True)
product_code = models.CharField(max_length=255, blank=True, null=True)
product_code_supplier = models.CharField(max_length=255, blank=True, null=True)
product_code_buyer = models.CharField(max_length=255, blank=True, null=True)
min_unit_state = models.CharField(max_length=255, blank=True, null=True)
state = models.CharField(max_length=255, blank=True, null=True)
vat_id = models.ForeignKey('VatRate')
unit_id = models.ForeignKey('Units')
category_id = models.ForeignKey('Category')
If you culd help me on this problem.

You should add a related name on the category_id field like:
category_id = models.ForeignKey('Category', related_name="product_services")
so that in your query you can do:
a = Category.objects.all().annotate(Count('product_services',distinct=True)).filter(type_id=1)
and then you can access the individual counts as:
a[0].product_services__count

Related

Django model ordering in another models

I can't find the answer to the following question about learning application building:
I have task model, which has one-to-many relations with other models: text_message, image_message, video_message, quiz_message, web_page_message (let's call them blocks) and I want to allow the user to choose the order in which these blocks will be sent.
The issue is that if I just add small integer field called 'order' in these blocks' classes - user still can choose a number that would be much bigger than the overall number of existing blocks.
So what is the best way to make such ordering?
Thank you for your answers.
UPD.:
Sorry if the code is not perfect, it is my first real Django project.
Added my models.
Questions: 
How to make an order through all these messages?
How to design models in such a way to give the ability to the user to change this ordering?
 
class task(models.Model):
employees_appointed_id = models.ManyToManyField(profile, related_name='task_to_appointed_users')
employees_finished_id = models.ManyToManyField(profile, related_name='task_to_users_finished', blank=True, null=True)
creator_user_id = models.ForeignKey('profile', on_delete=models.CASCADE, related_name='who_created_task')
description = models.TextField(max_length=1000)
created_datetime = models.DateTimeField(models.DateTimeField(auto_now=True))
deadline = models.DateTimeField(blank=True, null=True)
title = models.CharField(max_length=55)
course = models.ForeignKey('course', on_delete=models.CASCADE)
mentor = models.ManyToManyField(profile, blank=True, null=True, related_name='task_to_profile')
class text_message(models.Model):
text = models.CharField(max_length=3900)
number_by_order = models.IntegerField()
task = models.ForeignKey('task', on_delete=models.CASCADE, related_name='message_to_task')
creator_user_id = models.ForeignKey('profile', on_delete=models.CASCADE, related_name='message_to_creator_user')
course_id = models.ForeignKey('course', on_delete=models.CASCADE, related_name='messages_to_course')
created_datetime = models.DateTimeField(auto_now=True)
class video_message(models.Model):
description = models.CharField(max_length=1024)
media = models.ForeignKey('media', on_delete=models.CASCADE)
task = models.ForeignKey('task', on_delete=models.CASCADE, related_name='video_message_to_task')
class web_page_message(models.Model):
link = models.CharField(max_length=255)
description = models.TextField(max_length=2000, blank=True, null=True)
task = models.ForeignKey('task', on_delete=models.CASCADE, related_name='web_page_to_task')
class image_message(models.Model):
media = models.ForeignKey('media', on_delete=models.CASCADE)
description = models.TextField(max_length=1024)
task = models.ForeignKey('task', on_delete=models.CASCADE, related_name='image_message_to_task')
class quiz_message(models.Model):
question = models.CharField(max_length=300)
option_1 = models.CharField(max_length=100)
option_2 = models.CharField(max_length=100)
option_3 = models.CharField(max_length=100, blank=True, null=True)
option_4 = models.CharField(max_length=100, blank=True, null=True)
option_5 = models.CharField(max_length=100, blank=True, null=True)
option_6 = models.CharField(max_length=100, blank=True, null=True)
option_7 = models.CharField(max_length=100, blank=True, null=True)
option_8 = models.CharField(max_length=100, blank=True, null=True)
option_9 = models.CharField(max_length=100, blank=True, null=True)
option_10 = models.CharField(max_length=100, blank=True, null=True)
explanation = models.CharField(max_length=200, blank=True, null=True)
task = models.ForeignKey('task', on_delete=models.CASCADE, related_name='quiz_message_to_task')

Accessing a parent's model attributes from child model in django

please can anyone help me out am stuck i want to access items in the item model which i have referenced in the OrderItem model but am trying to access the item from Order model
here are the models
here is the model that am using to access
class Order(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL,on_delete=models.CASCADE)
ref_code = models.CharField(max_length=20)
items = models.ManyToManyField(OrderItem)
start_date = models.DateTimeField(auto_now_add=True)
order_date = models.DateTimeField()
ordered = models.BooleanField(default=False)
shipping_address = models.ForeignKey('Address',on_delete=models.SET_NULL,related_name='shipping_address',blank=True,null=True)
payment = models.ForeignKey('Payment',on_delete=models.SET_NULL,blank=True,null=True)
being_delivered = models.BooleanField(default=False)
received = models.BooleanField(default=False)
refund_requested = models.BooleanField(default=False)
refund_granted = models.BooleanField(default=False)
Here is the parent model which i want to access
class OrderItem(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL,on_delete=models.CASCADE)
ordered_order = models.BooleanField(default=False)
item = models.ForeignKey(Item, on_delete=models.CASCADE)
quantity = models.IntegerField(default=1)
and the item am trying to access must in this model
class Item(models.Model):
title = models.CharField(max_length=100)
price = models.IntegerField()
discount_price = models.IntegerField(blank=True, null=True)
category = models.ForeignKey(Categories, on_delete=models.DO_NOTHING)
tags = models.ManyToManyField(Tags, related_name='itemTags')
slug = models.SlugField(max_length=200, unique=True)
size = models.CharField(blank=True, null=True, max_length=5)
model = models.CharField(max_length=100, blank=True, null=True)
description = models.TextField()
quantity = models.IntegerField(default=1)
image = models.ImageField()
color = models.CharField(max_length=100, blank=True, null=True)
brand = models.CharField(max_length=100, blank=True, null=True)
Display = models.DecimalField(max_digits=100,
decimal_places=1,
blank=True,
null=True)
ram = models.CharField(max_length=100, blank=True, null=True)
material = models.CharField(max_length=100, blank=True, null=True)
hdd = models.CharField(max_length=100, blank=True, null=True)
size = models.CharField(max_length=100, blank=True, null=True)
lens = models.CharField(max_length=100, blank=True, null=True)
created_at = models.DateField(auto_now_add=True)
i was trying with this but seem not to work
recent_orders=Order.objects.filter(user=2)
for item in recent_orders:
print(item.items.item.title)
can anyone help me out Please!!!
You need thi code:
recent_orders=Order.objects.filter(user=2)
for order in recent_orders:
for order_item in order.items:
print(order_item.item.title)
try to give different names to all your variables, this will make programming more effective

django - Runpython function to turn charfield into foreignkey

I've been strugglin to relate a csv imported data model with a spatial data model based on a CharField.
I've created both models and now im trying to transfer the data from one field to a new one to be the ForeignKey field. I made a Runpython funtion to apply on the migration but it goives the an error:
ValueError: Cannot assign "'921-5'":
"D2015ccccccc.rol_fk" must be a "D_Base_Roles" instance.
Here are the models:
class D_Base_Roles(models.Model):
predio = models.CharField(max_length=254)
dest = models.CharField(max_length=254)
dir = models.CharField(max_length=254)
rol = models.CharField(primary_key=True, max_length=254)
vlr_tot = models.FloatField()
ub_x2 = models.FloatField()
ub_y2 = models.FloatField()
instrum = models.CharField(max_length=254)
codzona = models.CharField(max_length=254)
nomzona = models.CharField(max_length=254)
geom = models.MultiPointField(srid=32719)
def __str__(self):
return str(self.rol)
class Meta():
verbose_name_plural = "Roles"
class D2015ccccccc(models.Model):
id = models.CharField(primary_key=True, max_length=80)
nombre_archivo = models.CharField(max_length=180, blank=True, null=True)
derechos = models.CharField(max_length=120, blank=True, null=True)
dir_calle = models.CharField(max_length=120, blank=True, null=True)
dir_numero = models.CharField(max_length=120, blank=True, null=True)
fecha_certificado = models.CharField(max_length=50, blank=True, null=True)
numero_certificado = models.CharField(max_length=50, blank=True, null=True)
numero_solicitud = models.CharField(max_length=50, blank=True, null=True)
rol_sii = models.CharField(max_length=50, blank=True, null=True)
zona_prc = models.CharField(max_length=120, blank=True, null=True)
##NEW EMPTY FOREIGNKEY FIELD
rol_fk = models.ForeignKey(D_Base_Roles, on_delete=models.CASCADE, blank=True, null=True)
def __str__(self):
return str(self.numero_certificado)
class Meta:
managed = True
#db_table = 'domperm2015cip'
verbose_name_plural = "2015 Certificados Informaciones Previas"
ordering = ['numero_certificado']
The Runpython function:
def pop_rol(apps, schema_editor):
roles = apps.get_model('b_dom_edificacion', 'D2015ccccccc')
for r in roles.objects.all():
rol = roles
r.rol_fk = r.rol_sii
r.save()
D_Base_Roles.rol values are all unique, and 921-5 is one of those values.
What am I missing?
You probably need to assign an object, not a string. Change the line
r.rol_fk = r.rol_sii
to
r.rol_fk = D_Base_Roles.objects.get(rol=r.rol_sii)
Maybe adjust to whatever the correct field for looking up D_Base_Roles instances is.
Note: this will make a database query for every iteration of the for-loop

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

Cross Table Left Join, Django ORM

I have the following models:
class TradeDetails(models.Model):
created_timestamp = models.DateTimeField(db_column='CREATED_TIMESTAMP', primary_key=True)
trade_name = models.CharField(db_column='TRADE_NAME', max_length=45)
trade_image = models.CharField(db_column='TRADE_IMAGE', max_length=500, blank=True, null=True)
class Meta:
managed = False
db_table = 'TRADE_DETAILS'
class TradeNotifications(models.Model):
client_id = models.CharField(db_column='CLIENT_ID', primary_key=True, max_length=15)
created_timestamp = models.DateTimeField(db_column='CREATED_TIMESTAMP')
updated_timestamp = models.DateTimeField(db_column='UPDATED_TIMESTAMP', blank=True, null=True)
platform_notification = models.IntegerField(db_column='PLATFORM_NOTIFICATION', blank=True, null=True)
sms_notification = models.IntegerField(db_column='SMS_NOTIFICATION', blank=True, null=True)
email_notification = models.IntegerField(db_column='EMAIL_NOTIFICATION', blank=True, null=True)
caller_notification = models.IntegerField(db_column='CALLER_NOTIFICATION', blank=True, null=True)
caller_id = models.IntegerField(db_column='CALLER_ID', blank=True, null=True)
client_confirmation = models.IntegerField(db_column='CLIENT_CONFIRMATION', blank=True, null=True)
device_id = models.CharField(db_column='DEVICE_ID', max_length=256, blank=True, null=True)
platform = models.CharField(db_column='PLATFORM', max_length=15, blank=True, null=True)
ip_address = models.CharField(db_column='IP_ADDRESS', max_length=50, blank=True, null=True)
expired = models.IntegerField(db_column='EXPIRED', blank=True, null=True)
trade_sent = models.IntegerField(db_column='TRADE_SENT', blank=True, null=True)
class Meta:
managed = False
db_table = 'TRADE_NOTIFICATIONS'
unique_together = (('client_id', 'created_timestamp'),)
I want to perform a left join on another table on the same db using the following sql query:
SELECT TRADE_DETAILS.TRADE_NAME FROM TRADE_NOTIFICATIONS LEFT JOIN
TRADE_DETAILS ON TRADE_NOTIFICATIONS.CREATED_TIMESTAMP =
TRADE_DETAILS.CREATED_TIMESTAMP
Is there a more Django-Like way of doing this or should I just go with raw
sql?
Upon reading some answers I tried to do this :
TradeNotifications.objects.using('tradenotifications').all().values_list('trade_name', 'trade_details_created_timestamp')
but it raised an error :
django.core.exceptions.FieldError: Cannot resolve keyword 'trade_name' into field. Choices are: caller_id, caller_notification,
You can't join tables without some relationship between models such as foreign key with Django ORM. There must be a relationship between the models.
This relationship doesn't have to be in the db, it's enough if it's defined in the models, but I don't think this is possible with your TradeDetails and TradeNotifications models. It could be possible with your client_id field; you'd change it from CharField() to ForeignKey(). This is especially useful in cases when you only read from the database and you reverse engineer it and use them as non-managed models.

Categories