Displaying columns from multiple tables in Django - sql

im new with this django database querying.
how can i translate this into a django queryset
SELECT prod.item_code_id, prod.name, price.SRP
FROM inventory_product prod, inventory_pricing price
WHERE prod.item_code_id = price.item_code_id
class Product(models.Model):
item_code_id = models.AutoField(primary_key=True)
name = models.CharField(max_length=255)
description = models.CharField(max_length=255)
category = models.ForeignKey(Category)
color = models.ForeignKey(Color)
brand = models.ForeignKey(Brand)
item_size = models.ForeignKey(ItemSize)
class Pricing(models.Model):
product_id = models.AutoField(primary_key=True)
item_code = models.ForeignKey(Product)
supplier = models.ForeignKey(Supplier)
SRP = models.DecimalField(max_digits=5, decimal_places=2)

Daniel Roseman is right. Don't use SQL query unless you really need them.
In your example, Django ORM should be enough. It would be better if you posted you models, but it will look smth like:
for prod in Product.objects.all():
price = Pricing.objects.get(item_code=prod)
print prod.pk, prod.name, price.SRP

Related

how to combine two tables in django

There are two tables
Hookahs and tobacco for example
and for the basket model, you need to combine these two models, help
For example:
class Hookah(model.Model):
name = models.Charfield()
description = .....
price = .......
class Tabacco(model.Model):
name = models.Charfield()
description = .....
price = .......
and OrderItem model:
class OrderItem(model.Model):
and here I need to pass the top two models, as a product, how to do it?
i.e. combine Hookah and Tabacoo into one
please help me
If I understand correctly, you want a Basket model that stores a link to other types? You can do that by creating a parent model that each shopping item inherits from, or you can do it by using a GenericForeignKey which allows pointing to any model object. The shared parent model is probably better as you don't have to duplicate code for shopping items such as name, price, etc.
class ShoppingItem(model.Model)
name = models.Charfield()
description = .....
price = .......
class Hookah(ShoppingItem):
height = ....
class Tabacco(ShoppingItem):
flavour = ....
Then you can do something like one of the following:
class OrderItem(model.Model): # info on a single ordered item
item = models.ForeignKey(ShoppingItem, on_delete=models.DO_NOTHING)
class Basket(model.Model): # basket of many `ShoppingItem`
items = models.ManyToManyField(ShoppingItem)
I think in this case, you should probably look at building a single product model and have a type attribute separate the product types. That way you can FK to a single product model with your order item model.
Something like this:
models.py
class Type(models.Model):
...
name = models.CharField(max_length=50)
...
class Product(models.Model)
name = models.CharField(max_length=150)
description = models.TextField()
type = models.ForeignKey(Type, on_delete=models.DO_NOTHING)
class Order(models.Model):
...
product = models.ForeignKey(Product, on_delete=models.DO_NOTHING)
....

Django equivalent for SQL query using INNER JOIN -clause

I would like to know the django equivalent for the SQL-query that uses the INNER JOIN -clause. I have two models that are linked with ForeignKey.
class Item(models.Model):
item_name = models.CharField(max_length=100)
item_is_locked = models.BooleanField(default=False)
class Request(models.Model):
item = models.ForeignKey(Item, on_delete=models.CASCADE)
item_owner = models.ForeignKey(settings.AUTH_USER_MODEL)
message_body = models.TextField(max_length=5000, null=True)
I want to get fields from the Request-table which has the "item_is_locked" value set to false in Item-table
If using SQL-query I would use this:
SELECT Request.item_owner,Request.message_body FROM Request INNER JOIN Item ON Request.item_id=Item.id AND Item.item_is_locked=False;
You can use filter and only to get desired result.
Try:
Request.objects.filter(item__item_is_locked=False).only('item_owner', 'message_body')

ORM Django LEFT JOIN + GROUP BY

I have following models in my Django project:
class Player(models.Model):
name = models.CharField()
class Team(models.Model):
name = models.CharField()
class Membership(models.Model):
player = models.ForeignKey(Player)
team = models.ForeignKey(Team)
date_joined = models.DateField()
date_leaved = models.DateField(blank=True, null=True)
And I want to create view on Django level which would perform that:
CREATE VIEW last_contract_expire AS
SELECT Player.name, MAX(Membership.date_leaved)
FROM player LEFT OUTER JOIN membership ON membership.player.id=player.id
GROUP BY player.id;
Django currently does not support SQL views (see this ticket). Django also does not support SQL GROUP BY directly. Anyway, you could achieve it like this:
def last_contract_expire():
return Player.objects.all().annotate(max_date_leaved=Max('membership__date_leaved'))
This will return all players and each player will have attributes name and max_date_leaved. Hope this helps

representing manytomanyfield with extra attributes in django

I have a situation where i need to store a table of "Product"'s and a table of "Order"'s on these products.
One order consists of many ("Product", "Quantity") tuples where quantity is a float expressed in tonnes.
I considered the followng implementation, but i don't think having a table of arbitrary products and quantities would be a very good design decision.
class Product(models.Model):
name = models.CharField("Name", max_length=50)
description = models.TextField("Description", blank=True)
class ProductOrder(models.Model):
unit = "tonnes"
product = models.ManyToManyField('Product')
quantity = models.FloatField('Quantity')
class Order(models.Model):
products = models.ManyToManyField('ProductOrder')
date = models.DateField('Date')
Am I overlooking an obvious solution? How would you implement this relationship to lead to the most DRY code. (PS. I don't want to have separate lists of products and quantities and have to rely implicitly on their ordering.)
In django, you can use through to create such intermediate table and maintain order specific attributes in there.
You can implement it as
class Product(models.Model):
name = models.CharField("Name", max_length=50)
description = models.TextField("Description", blank=True)
class Order(models.Model):
products = models.ManyToManyField('Product', through="OrderDetail")
date = models.DateField('Date')
class OrderDetail(models.Model):
unit = "tonnes"
product = models.ForeignKey('Product')
order = models.ForeignKey('Order')
quantity = models.FloatField('Quantity')
The documentation explains how to use and work with such design.

Django annotate code

Just stumbled upon some guy code
He have models like this
class Country(models.Model):
name = models.CharField(max_length=100)
class TourDate(models.Model):
artist = models.ForeignKey("Artist")
date = models.DateField()
country = models.ForeignKey("Country")
And is querying like this
ireland = Country.objects.get(name="Ireland")
artists = Artist.objects.all().extra(select = {
"tourdate_count" : """
SELECT COUNT(*)
FROM sandbox_tourdate
JOIN sandbox_country on sandbox_tourdate.country_id = sandbox_country.id
WHERE sandbox_tourdate.artist_id = sandbox_artist.id
AND sandbox_tourdate.country_id = %d """ % ireland.pk,
}).order_by("-tourdate_count",)
My question is why He have underscores like sandbox_tourdate but it isn't in model field
Is that created automatically like some sort of pseudo-field?
sandbox_tourdate isn't the name of the field, it's the name of the table. Django's naming convention is to use appname_modelname as the table name, although this can be overridden. In this case, I guess the app is called 'sandbox'.
I don't really know why that person has used a raw query though, that is quite easily expressed in Django's ORM syntax.