Django View Table

ulr0
5 min readFeb 22, 2023

View Table?

  • 실제로 존재하는 테이블을 기반으로 만드는 데이터가 저장되지 않는 가상 테이블이다.
  • 필요한 데이터만 View Table에서 정의해서 처리할 수 있기 때문에 관리가 용이하고 쿼리문이 간단해진다.
  • 매번 복잡한 쿼리문이 수행되지 않고, 이미 만들어진 View Table에서 데이터를 가져오기 때문에 쿼리문 처리 속도가 빨라진다.

Django로 View Table 만들기

  1. 필요한 데이터를 SQL Select문을 작성한다.
SELECT 
pc.id AS category_id,
ps.id AS subcategory_id,
p.id AS product_id,
ph.name AS product_name,
ph.price,
ph.discount_price,
p.main_image_url,
s.name AS seller_name
FROM product_histories AS ph
INNER JOIN products AS p
ON p.id = ph.product_id
INNER JOIN sellers AS s
ON s.id = p.seller_id
INNER JOIN product_subcategories AS ps
ON ps.id = p.product_subcategory_id
INNER JOIN product_categories AS pc
ON pc.id = ps.product_category_id
WHERE (ph.product_id, ph.updated_at) IN (
SELECT
ph.product_id, MAX(ph.updated_at)
FROM product_histories AS ph
GROUP BY ph.product_id
)
AND ph.is_displayed = true
AND ph.is_deleted = false
ORDER BY ph.updated_at desc;

2. MySQL로 View Table 만들어준다.

CREATE OR REPLACE VIEW product_lists AS [1]
SELECT
row_number() OVER () as id, [2]
pc.id AS category_id,
ps.id AS subcategory_id,
.
.
.
AND ph.is_displayed = true
AND ph.is_deleted = false
ORDER BY ph.updated_at desc;

[1] CREATE OR REPLACE VIEW {테이블 이름}

[2] 위에서 만든 SELECT문의 첫 줄에 컬럼 하나를 추가해준다.

3. Django 앱의 models.py에 View Table을 정의한다.

class ProductList(models.Model):
category = models.ForeignKey(ProductCategory, on_delete=DO_NOTHING) [1]
subcategory = models.ForeignKey(ProductSubcategory, on_delete=DO_NOTHING)
product = models.ForeignKey(Product, on_delete=DO_NOTHING)
product_name = models.CharField(max_length=100)
price = models.DecimalField(max_digits=10, decimal_places=2)
discount_price = models.DecimalField(max_digits=10, decimal_places=2)
main_image_url = models.URLField(max_length=2000)
seller_name = models.CharField(max_length=30)

class Meta:
managed = False [2]
db_table = 'product_lists' [3]

[1] DB에 존재하는 테이블과 연결할 컬럼에 on_delete=DO_NOTHING 조건을 설정해야 한다. 일반적으로 View Table에는 데이터가 존재하지 않으니 delete() 메서드를 호출할 일은 없지만 DO_NOTHING 설정을 하지 않으면 일부 테스트케이스가 실패할 수도 있다고 한다. 테스트케이스 실행 후 테스트 데이터베이스의 auto cleaning mechanism과 관련이 있을 수 있다.

[2] class Meta에 managed = False 설정을 한다. django의 자동 migration을 막아서 View Table을 데이터베이스에 물리적으로 만들지 않도록 해준다.

[3] db_table에 View Table의 이름을 설정한다. Django ORM이 데이터를 검색할 database 엔티티를 알게 하기 위함이다.

4. 필요할 때 import해서 사용한다.

from models import ProductList

ProductList.objects.all()
ProductList.objects.filter(조건들)

--

--