모델 정의
class Product(models.Model):
name = models.CharField(max_length=30)
price = models.IntegerField(default=0)
stock = models.IntegerField(default=0)
Create
>>> from polls.models import Product
>>> p = Product(name="coffee", price=4000, stock=1)
>>> p.save()
>>> p = Product(name=“water", price=1000, stock=10)
>>> p.save()
>>> p = Product(name=“chocolate", price=5000, stock=20)
>>> p.save()
bulk Create
>>> products = [(“coffee", 4000, 1), (“water”, 1000, 10), (“chocolate”, 5000, 20)]
>>> bulk_list = []
>>> for p in products:
bulk_list.append(Product(name=[0], price=p[1], stock=p[2]))
>>> Product.objects.bulk_create(bulk_list)
Delete
>>> p = Product.objects.get(id=6)
>>> p.delete()
>>> p = Product.objects.get(id=6)
Product.DoesNotExist: Product matching query does not exist.
Bulk delete
>>> p = Product.objects.filter(id__in=[4, 5]).delete()
update
>>> p = Product.objects.get(id = 1)
>>> p.price = 100
>>> p.save()
>>> products = Product.objects.all()
>>> for p products:
p.price = 100
p.save()
Ef) 배열의 index로 접근하여 update는 안됨!! (정보만 볼수 있음)
>>> products[0].price = 100
>>> products[0].save() # 동작 안함
Bulk update
>>> Product.objects.update(price=4000)
Select ( in / not in )
1, 3번 데이터만 가져오고 싶을때
>>> Product.objects.filter(id__in=[1, 3])
>>> exclude_list = [2]
>>> Product.objects.exclude(id__in=exclude_list)
>>> Product.objects.filter(name__contains='e')
.filter(id__in=[1, 3])
.exclude(id__in=[1])
union
>>> p1 = Product.objects.filter(id=1)
>>> p2 = Product.objects.filter(id=2)
>>> p1.union(p2)
subquery
>>> from django.db.models import Subquery
>>> p = Product.objects.all()
>>> return_obj = p.filter(id=Subquery(Product.objects.filter(id=2).values('id')))
>>> return_obj.query
>>> return_obj.explain()
Sql : select * from polls_product as pp,
(select id from polls_product as p2 where p2.id = 2) pp2
where pp.id = pp2.id
Q() : 쿼리 담당!! ( filter의 조건을 쉽게 쓰자)
>>> from django.db.models import Q
>>> Product.objects.filter(Q(name="coffee"))
>>> Product.objects.filter(name="coffee")
And
>>> Product.objects.filter(Q(name="coffee"), Q(price__lte=10000))
>>> Product.objects.filter(name="coffee", price__lte=10000)
or
>>> Product.objects.filter(Q(name="coffee") | Q(name="water"))
>>> Product.objects.filter(name="coffee") | Product.objects.filter(name="water")
Not
>>> Product.objects.filter(~Q(name="coffee"))
>>> Product.objects.exclude(name="coffee")
in
>>> Product.objects.filter(Q(name__in=["coffee", "water"]))
>>> Product.objects.filter(name__in= ["coffee", "water"])
Like + and + not in
>>> Product.objects.filter(name__contains="e")
.filter(id__in=[1, 3])
.exclude(id__in=[1])
>>> Product.objects.filter(Q(name__contains="e") & Q(id__in=[1, 3]) & ~Q(id__in=[1]))
Union
>>> p1 = Product.objects.filter(Q(id=1))
>>> p2 = Product.objects.filter(Q(id=2))
>>> p1.union(p2)
쿼리 확장
>>> query_dict = { 'name__contains': 'e', 'pk__in' : [1, 3] }
>>> Product.objects.filter(**query_dict)
>>> import operator
>>> from functools import reduce
>>> predicates = [('id__in', [1, 2, 3]), ('name__contains', 'o')]
>>> query_list = [Q(x) for x in predicates]
>>> Product.objects.filter(reduce(operator.and_, query_list))
>>> Product.objects.filter(reduce(operator.and_, query_list), **query_dict)
F() : 데이터베이스에서 모델 필드 값을 직접 참조하는 데 사용
모든 product price 가격을 20% 인상
>>> products = Product.objects.all()
>>> for product in products:
product.price *= 1.2
product.save()
cf) 일괄 업데이트 (모든 product price를 4000으로 업데이트)
>>> Product.objects.update(price=4000)
F() 사용
주의!! F() 모델을 객체에 저장 후 유지 됨
>>> product = Product.objects.get(pk=1)
>>> product.price
4000
>>> product.price = F('price') + 1
>>> product.price
<CombinedExpression: F(price) + Value(1)>
>>> product.save() # price 4001
>>> product.price
<CombinedExpression: F(price) + Value(1)>
>>> product.name = 'F() test'
>>> product.save(). # price 4002
>>> product = Product.objects.get(pk=1)
>>> product.price
4002
>>> product.price = F('price') + 1
>>> product.save()
>>> product.price
<CombinedExpression: F(price) + Value(1)>
>>> product.refresh_from_db()
>>> product.price
4001
두 필드에 대한 연산 ( 파이썬으로 하지 않기 )
-
F()를 쓰지 않으면 inner select로 가져와야 함
-
두필드의 연산이 다른 타입이면 해당 타입을 알려줘야 한다. (ExpressionWrapper 사용)
>>> p = Product.objects.annotate(price_stock=F('price')-F('stock'))
>>> from django.db.models import ExpressionWrapper, DecimalField
>>> p = Product.objects.all().annotate(
value_in_stock=ExpressionWrapper(
F('price') * F('stock'), output_field=DecimalField()
)
)
>>> from django.db.models import CharField
>>> p = Product.objects.all().annotate(
value_in_stock=ExpressionWrapper(
Concat(F('name'), F('stock')), output_field=CharField()
)
)
'web > Django' 카테고리의 다른 글
django query 기초 3 (0) | 2020.03.25 |
---|---|
django query 기초2 (0) | 2020.02.18 |
[django] 데이터베이스 여러개 사용하기 (django multi db) (2) | 2020.02.11 |
django cross domain allow middleware (0) | 2019.08.16 |
django migrate 칼럼이 생성 안될때 ( 꼬였을때) (0) | 2019.08.09 |