I need to re-write raw-sql to django-orm. But unfortunately I can't do it. Does someone has ideas ?:
HttcOrder.objects.raw('''SELECT httc_order.id, httc_order.price, httc_order.quantity,
SUM(markedskraft_trade.qty) as positions_quantity
FROM httc_order left outer join markedskraft_trade on httc_order.id = markedskraft_trade.httc_order_id
WHERE httc_order.order_status in ('new', 'pending', 'confirmed')
and httc_order.mk_contract_id = %s
group by httc_order.id
having positions_quantity is NULL or quantity - positions_quantity > 0
order by httc_order.price desc''', [contract.id])
Example of models:
httc:
class Order(models.Model):
quantity = models.IntegerField(verbose_name=_('Qty'))
order_status = models.CharField(max_length=10, choices=ORDER_STATUSES, default=NEW)
price = models.IntegerField(verbose_name=_('Prc'))
mk_contract = models.ForeignKey(
Contract, related_name='httc_orders', verbose_name=_('Markedskraft contract')
)
....
markedskraft:
class Trade(models.Model):
order_id = models.IntegerField(blank=True, null=True, db_index=True)
httc_order_id = models.ForeignKey(HttcOrder, blank=True, null=True, db_index=True)
qty = models.IntegerField()
.......
Related
I am trying to convert sql code to django orm code.
I don't want to use python raw function
SELECT
u.`user_id` as 'dp_id',
cp.`email` as 'dp_email',
cp.`name` as 'dp_name',
u2.`user_id` as 'cm_id',
cp2.`email` as 'cm_email',
cp2.`name` as 'cm_name'
FROM `user` u
INNER JOIN customer_profile cp
ON u.`customer_profile_id` = cp.`id`
INNER JOIN branch_user bm
ON bm.`child_user_id` = u.`user_id`
AND bm.`parent_role_id` = 14
AND bm.`is_deleted` = 0
INNER JOIN user u2
ON u2.`user_id` = bm.`parent_user_id`
AND u2.`is_deleted` = 0
INNER JOIN customer_profile cp2
ON u2.`customer_profile_id` = cp2.`id`
WHERE u.`user_id` = ?
AND u.`is_deleted` = 0
I did something like this :
cp_emails = User.objects.filter(branch_user_childUser__parent_role_id=14, branch_user_childUser__is_deleted=0).select_related('customer_profile').prefetch_related('branch_user_childUser')
But i am not able to add user u2 to django orm as it's same user table and that too compare with "bm" i.e this line "ON u2.user_id = bm.parent_user_id"
My models:
class User(models.Model):
user_id = models.AutoField(primary_key=True)
customer_profile = models.ForeignKey(
'login.CustomerProfile', on_delete=models.CASCADE, default=None
)
class BackboneUserManagerMapping(models.Model):
child_user = models.ForeignKey('login.User', related_name='branch_user_childUser', on_delete=models.DO_NOTHING)
parent_user = models.ForeignKey('login.User', related_name='branch_user_childUser', on_delete=models.DO_NOTHING)
parent_role_id = models.IntegerField()
is_deleted = models.BooleanField(default=False)
class CustomerProfile(AbstractBaseUser, PermissionsMixin):
id = models.AutoField(primary_key=True)
email = models.EmailField(default=None, unique=True)
mobile = models.CharField(max_length=13, default=None)
alt_mobile = models.CharField(max_length=13, null=True)
name = models.CharField(max_length=255, default=None)
Models:
Items(models.Model):
name = models.CharField(max_length=250, verbose_name="Item Name")
created_date = models.DateTimeField(auto_now_add=True)
Accounts(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
url_tag = models.CharField(max_length=200)
item = models.ForeignKey(Items, on_delete=models.CASCADE)
Comments(models.Model):
item = models.ForeignKey(Items, on_delete=models.CASCADE, null=True)
comment = models.TextField(null=True)
url_tag = models.URLField(null=True)
is_flagged = models.BooleanField(default=False, null=True)
response_required = models.BooleanField(default=True)
created_date = models.DateTimeField(auto_now_add=True)
Responses(models.Model):
response = models.TextField()
comment = models.ForeignKey(Comments, on_delete=models.CASCADE)
created_date = models.DateTimeField(auto_now_add=True)
Sql Query:
select c.id as comment_id, c.created_date, c.is_flagged, c.response_required
from comments as c
left join responses as r on c.id = r.comment_id
inner join items as i on i.id = c.item_id and r.comment_id is null
left join accounts as a on
(a.item_id = c.item_id and lower(a.url_tag) = lower(c.url_tag)
where c.id in (12, 32, 42, 54)
ORDER BY c.created_date desc, comment_id desc;
What I tried:
filters = {
'id__in': [12, 32, 42, 54]
}
comment_objs = Comment.objects.filter(**filters)
.select_related('commentsresponses', 'item')
.order_by('-created_date', '-id')
I want to get list of comment objects after joining and applying filters.
Maybe we can use serializers here i don't know since I don't have much experience with django
If time complexity doesn't matter for you, You can use raw SQL query:
from django.db import connection
cursor = connection.cursor()
cursor.execute('''select c.id as comment_id, c.created_date, c.is_flagged,
c.response_required
from comments....''')
I have a table called product_type & Product.
class Product_type(models.Model):
product_type_id = models.AutoField(primary_key=True)
product_type_name = models.CharField(max_length=255, null = False, unique=True)
product_type_title = models.CharField(max_length=255, null = True)
product_type_description = models.TextField(null = False)
product_type_slug = models.SlugField(unique=True, blank=True, null=True)
category = models.ForeignKey(Category, on_delete=models.SET_NULL, null=True, related_name='category')
created_at = models.DateTimeField(auto_now_add = True)
updated_at = models.DateTimeField(auto_now = True)
class Product(models.Model):
product_id = models.AutoField(primary_key=True)
product_name = models.CharField(max_length=255, null = False, unique=True)
product_slug = models.SlugField(unique=True, blank=True, null=True)
product_title = models.CharField(max_length=255, null = True)
product_info = models.TextField(null = False)
product_description = models.CharField(max_length = 255)
product_price = models.CharField(max_length = 255)
brand = models.ForeignKey(Brand, on_delete=models.SET_NULL, null=True)
product_type = models.ForeignKey(Product_type, on_delete=models.SET_NULL, null=True)
product_status = models.CharField(max_length = 100, default = "publish")
created_at = models.DateTimeField(auto_now_add = True)
updated_at = models.DateTimeField(auto_now = True)
class Brand(models.Model):
brand_id = models.AutoField(primary_key=True)
brand_name = models.CharField(max_length=255, null = False, unique=True)
brand_slug = models.SlugField(unique=True, blank=True, null=True)
brand_title = models.CharField(max_length = 255)
brand_logo = models.ImageField(upload_to = 'brand/logo/%Y/%m/')
brand_logo_alt_text = models.CharField(max_length=255, null = False)
brand_info = models.TextField(null = False)
brand_description = models.CharField(max_length = 255)
category = models.ForeignKey(Category, on_delete=models.SET_NULL, null=True)
country = models.ForeignKey(Country, default = '1', on_delete=models.SET_DEFAULT, null=True)
brand_status = models.CharField(max_length = 100, default = "publish")
created_at = models.DateTimeField(auto_now_add = True)
updated_at = models.DateTimeField(auto_now = True)
in product table I've linked brand table as brand and product_type table as product_type, so suppose I've multiple records for each brand in product table. So I only want 1 record for each brand which has a lowest product_price and that record must match with product_type.
for example:
I want only those product which contains product_type = 'accounting'.
so here is a demo data:
product(model data)
product_id:1,product_name:abc, product_type: accounting, brand:aaa, price:$100
product_id:2,product_name:xyz, product_type: accounting, brand:aaa, price:$50
product_id:3,product_name:bdf, product_type: accounting, brand:bbb, price:$150
product_id:4,product_name:ghf, product_type: other, brand:ccc, price:$150
so my query result will be product_id 2,3 because 1,2 have same brand but 2 has the lowest price & 2,3 both have product_type = accounting.
I tried too much but nothing works.
I want your help!
First, use models.DecimalField for product prices. Do not use models.CharField for numbers. Change the product_price field to product_price = models.DecimalField(max_digits=6, decimal_places=2) (Stores $0 to $9999.99).
Then, you can try the following:
from django.db.models import F, Min
Product.objects.filter(
product_type=my_product_type
).annotate(
min_brand_price=Min('brand__product_type__product_price')
).filter(
product_price=F('min_brand_price')
)
Other related questions on StackOverflow:
How to get only latest record on filter of foreign key django
Django model get unique foreign key rows based on other column max value
I have the following models
models
class User(models.Model):
ur_id = models.AutoField(primary_key=True)
ur_mailid = models.CharField(max_length=100)
...
class User_info(models.Model):
ui_id = models.AutoField(primary_key=True)
# ui_iduser = models.IntegerField()
ui_iduser = models.ForeignKey(User, on_delete=models.CASCADE)
ui_firstname = models.CharField(max_length=45)
ui_lastname = models.CharField(max_length=45)
...
class User_group(models.Model):
ug_id = models.AutoField(primary_key=True)
ug_groupname = models.CharField(max_length=100)
...
class User_groupmember(models.Model):
# ug_groupid = models.IntegerField()
# ug_userid = models.IntegerField()
ug_groupid = models.ForeignKey(User_group, on_delete=models.CASCADE)
ug_userid = models.ForeignKey(User, on_delete=models.CASCADE)
...
Here is SQL Query:
select
a.ur_id ur_id,
c.ug_id ug_id,
d.ui_mailid ui_mailid,
d.ui_firstname ui_firstname,
d.ui_lastname ui_lastname
from user a
LEFT OUTER JOIN
user_groupmember b ON a.ur_id = b.ug_userid
LEFT OUTER JOIN
user_group c ON c.ug_id = b.ug_userid
LEFT OUTER JOIN
user_info d ON d.ui_id = a.ur_id
where a.ur_mailid = 'test#test.com'
I need to convert it in ORM Query.
Is there any way to achieve it without using raw SQL?
Any help is appreciated
I got problem in making Queries. In the shell I all the time faced 'user' has no split error. and want to know how to make query about those models.
select i.id, i.name, i.email, i.memo, g.id, g.name, i.birthday, i.regdt, n.number, t.name, t.id
from webcontact_info as i
inner join webcontact_number as n on i.id = n.info_id
inner join webcontact_group as g on i.group_id = g.id
inner join webcontact_type as t on n.type_id = t.id;
this query in mysql. how can i change into query for Django?
please help me about this.
those are models.py
class Group(models.Model):
name = models.CharField(max_length=20)
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
class Type(models.Model) :
name = models.CharField(max_length=20)
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
class Info(models.Model):
name = models.CharField(max_length=20)
email = models.EmailField(null=True, blank=True, unique=True)
memo = models.CharField(max_length=200, null=True)
birthday = models.CharField(max_length=12,null=True, blank=True)
group = models.ForeignKey(Group, on_delete=models.CASCADE)
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
regdt = models.DateTimeField(auto_now_add=True)
updatedt = models.DateTimeField(auto_now_add=True)
class Number(models.Model):
number = models.CharField(max_length=11)
info = models.ForeignKey(Info, on_delete=models.CASCADE)
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
type = models.ForeignKey(Type, on_delete=models.CASCADE)
regdt = models.DateTimeField(auto_now_add=True)
updatedt = models.DateTimeField(auto_now_add=True)
You can just use your related object with your object. But maybe you're looking for select_related.
It will return selecting additional related-object data - It will boost query performance bit much.
infos = Info.objects.select_related('user', 'group', 'user__number').
Check more detail in django docs