I have the following schema:
class PCs(models.Model):
model = models.ForeignKey(Products, primary_key=True)
speed = models.IntegerField(max_length=256, blank = True, null=True)
ram = models.IntegerField(max_length=256, blank = True, null=True)
hd = models.IntegerField(max_length=256, blank = True, null=True)
price = models.IntegerField(max_length=256, blank = True, null=True)
class Printers(models.Model):
model = models.ForeignKey(Products, primary_key=True)
color = models.BooleanField()
type = models.CharField(max_length=256, blank = True, null=True)
price = models.IntegerField(max_length=256, blank = True, null=True)
I'm trying to run the following SQL query:
SELECT *
FROM PCs P, Printers T
WHERE p.price + t.price <= 1000
But I'm completely lost on how to do this with Django's ORM. Is the only way to do this but getting all the objects from both PCs and Printers and checking all possible combinations?
ORM:
pcs = PCs.objects.filter(price__lte=1000)
printers = Printers.objects.filter(price__lte=1000)
In pcs
and printer
we can found answer to the question. And our SQL
inquiry is no correctly. Or make a related_name, and make one query from product.
A possible solution is to use raw SQL, see documentation here.
Unfortuantely, the django ORM doesn't provide a clean way to join 2 tables that don't have some kind of relationship. Just because it isn't clean doesn't mean you can't do it!
Note that I can't actually tell what your raw sql table names are, so you'll have to fill that in yourself. If I had to guess they would be app_name_p_cs
and app_name_printers
. You can use ./manage.py dbshell
to go find out.
You could try something like:
pcs = PCs.objects.raw(
"SELECT "
" pc_table.model_id, "
" pc_table.speed, "
" pc_table.ram, "
" pc_table.hd, "
" pc_table.price, "
" printer_table.model_id as printer_model_id, "
" printer_table.color as printer_color, "
" printer_table.type as printer_type, "
" printer_table.price as printer_price "
"FROM "
" pc_table, printer_table "
"WHERE "
" pc_table.price + printer_table.price <= 1000 "
)
pairs = []
for pc in pcs:
printer = Printers(
model_id=pc.printer_model_id,
color=pc.printer_color,
type=pc.printer_type,
price=pc.printer_price,
)
pairs.append((pc, printer))
As you can see, the extra values from the printer fields are just tacked on to the pc object you get with your ORM query, you just have to construct the printer object manually after that. I think it is a good idea to name the printer fields for the query so that the ORM does not confuse them for pc fields.
Also note that depending on what you plan to do with the result of this query, it may not even be necessary to construct the Printers
objects at all.
I have the following schema:
class PCs(models.Model):
model = models.ForeignKey(Products, primary_key=True)
speed = models.IntegerField(max_length=256, blank = True, null=True)
ram = models.IntegerField(max_length=256, blank = True, null=True)
hd = models.IntegerField(max_length=256, blank = True, null=True)
price = models.IntegerField(max_length=256, blank = True, null=True)
class Printers(models.Model):
model = models.ForeignKey(Products, primary_key=True)
color = models.BooleanField()
type = models.CharField(max_length=256, blank = True, null=True)
price = models.IntegerField(max_length=256, blank = True, null=True)
I'm trying to run the following SQL query:
SELECT *
FROM PCs P, Printers T
WHERE p.price + t.price <= 1000
But I'm completely lost on how to do this with Django's ORM. Is the only way to do this but getting all the objects from both PCs and Printers and checking all possible combinations?
ORM:
pcs = PCs.objects.filter(price__lte=1000)
printers = Printers.objects.filter(price__lte=1000)
In pcs
and printer
we can found answer to the question. And our SQL
inquiry is no correctly. Or make a related_name, and make one query from product.
A possible solution is to use raw SQL, see documentation here.
Unfortuantely, the django ORM doesn't provide a clean way to join 2 tables that don't have some kind of relationship. Just because it isn't clean doesn't mean you can't do it!
Note that I can't actually tell what your raw sql table names are, so you'll have to fill that in yourself. If I had to guess they would be app_name_p_cs
and app_name_printers
. You can use ./manage.py dbshell
to go find out.
You could try something like:
pcs = PCs.objects.raw(
"SELECT "
" pc_table.model_id, "
" pc_table.speed, "
" pc_table.ram, "
" pc_table.hd, "
" pc_table.price, "
" printer_table.model_id as printer_model_id, "
" printer_table.color as printer_color, "
" printer_table.type as printer_type, "
" printer_table.price as printer_price "
"FROM "
" pc_table, printer_table "
"WHERE "
" pc_table.price + printer_table.price <= 1000 "
)
pairs = []
for pc in pcs:
printer = Printers(
model_id=pc.printer_model_id,
color=pc.printer_color,
type=pc.printer_type,
price=pc.printer_price,
)
pairs.append((pc, printer))
As you can see, the extra values from the printer fields are just tacked on to the pc object you get with your ORM query, you just have to construct the printer object manually after that. I think it is a good idea to name the printer fields for the query so that the ORM does not confuse them for pc fields.
Also note that depending on what you plan to do with the result of this query, it may not even be necessary to construct the Printers
objects at all.
0 commentaires:
Enregistrer un commentaire