Search

Django Mixin ์‚ฌ์šฉ๋ฒ•

Intro

Django์˜ CBV(Class Based View)๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ, Mixin์„ ํ™œ์šฉํ•˜๋ฉด ํ•„์š”ํ•œ ๊ธฐ๋Šฅ์„ ์†์‰ฝ๊ฒŒ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์˜ˆ๋ฅผ ๋“ค์–ด RetrieveAPIView๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š”๋ฐ Create ๊ธฐ๋Šฅ์ด ํ•„์š”ํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด CreateModelMixin์„ ์ƒ์†๋ฐ›์•„ Create ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
# ์ž˜๋ชป๋œ ์‚ฌ์šฉ class ProductRetrieveCreateView(RetrieveAPIView, CreateModelMixin): pass
Python
๋ณต์‚ฌ
๋‹ค๋งŒ Mixin์„ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋ช‡ ๊ฐ€์ง€ ๊ณ ๋ คํ•ด์•ผ ํ•˜๋Š” ์‚ฌํ•ญ์ด ์žˆ์Šต๋‹ˆ๋‹ค.
Django CBV์™€ Mixin์„ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ๊ฐ„๋‹จํ•˜๊ฒŒ ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

Rule of Thumb

Mixin์„ ์‚ฌ์šฉํ•  ๋•Œ <Two Scoops of Django 3.x>์—์„œ ์ถ”์ฒœํ•˜๋Š” ์‚ฌ์šฉ ๋ฐฉ๋ฒ•์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.
1.
Django๊ฐ€ ์ œ๊ณตํ•˜๋Š” Base View Class๋Š” ๊ฐ€์žฅ ์˜ค๋ฅธ์ชฝ์— ๋‘”๋‹ค.
2.
Mixin์€ Base View์˜ ์™ผ์ชฝ์— ๋‘”๋‹ค.
3.
๋˜ํ•œ Mixin์€ ์–ด๋–ค Class๋กœ๋ถ€ํ„ฐ๋ผ๋„ ์ƒ์†์„ ๋ฐ›์•„์„œ ์•ˆ ๋œ๋‹ค.
์œ„์˜ ๋ฐฉ๋ฒ•์„ ์ ์šฉํ•œ ์˜ˆ์‹œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.
from django.views.generic import TemplateView class FreshFruitMixin: def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context["has_fresh_fruit"] = True return context class FruityFlavorView(FreshFruitMixin, TemplateView): template_name = "fruity_flavor.html"
Python
๋ณต์‚ฌ
์œ„์˜ ์˜ˆ์‹œ์—์„œ ์ฃผ์˜ ๊นŠ๊ฒŒ ๋ณด์•„์•ผ ํ•˜๋Š” ์ ์€
1.
FruitFlavorView์˜ ์ƒ์† ์ˆœ์„œ์—์„œ FreshFruitMixin์ด TemplateView ๋ณด๋‹ค ์™ผ์ชฝ์— ์žˆ๊ณ 
2.
FreshFruitMixin์ด ๋‹ค๋ฅธ ํด๋ž˜์Šค๋กœ๋ถ€ํ„ฐ ์ƒ์† ๋ฐ›์ง€ ์•Š๋Š” ํด๋ž˜์Šค๋ผ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

Why?

์™œ ์œ„์™€ ๊ฐ™์€ ๋ฐฉ๋ฒ•์„ ์ถ”์ฒœํ•˜๋Š” ๊ฑธ๊นŒ์š”?
์ •๋‹ต์€ Python์˜ MRO(Method Resolution Order)์™€ ๊ด€๋ จ ์žˆ์Šต๋‹ˆ๋‹ค.
Python์€ ๋‹ค์ค‘ ์ƒ์†์„ ๋ฐ›์€ ํด๋ž˜์Šค์—์„œ attribute๋‚˜ method๋ฅผ ํƒ์ƒ‰ํ•  ๋•Œ, C3 Linearization ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
C3 Linearization ์•Œ๊ณ ๋ฆฌ์ฆ˜ ํ•œ ๋ฌธ์žฅ์œผ๋กœ ํ‘œํ˜„ํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค:
depth-first until classes are encountered that will share a parent, and then breadth-first over those ...
attribute๋‚˜ method ํƒ์ƒ‰ ์‹œ์—
1.
๋จผ์ € ํ˜„์žฌ ํด๋ž˜์Šค์—์„œ ์ฐพ์Šต๋‹ˆ๋‹ค.
2.
ํ˜„์žฌ ํด๋ž˜์Šค์—์„œ ์ฐพ์ง€ ๋ชปํ•˜๋ฉด ๋ถ€๋ชจ ํด๋ž˜์Šค๋กœ ์ด๋™ํ•˜์—ฌ depth-first ํƒ์ƒ‰์„ ํ•ฉ๋‹ˆ๋‹ค.
3.
ํƒ์ƒ‰ ์ค‘ ๊ณต์œ ๋˜๋Š” parent class๋ฅผ ๋งŒ๋‚˜๋ฉด ๋Œ์•„๊ฐ€์„œ breadth-first ํƒ์ƒ‰์„ ํ•ฉ๋‹ˆ๋‹ค.
์˜ˆ์‹œ๋ฅผ ํ†ตํ•ด์„œ ๋” ์ž์„ธํ•˜๊ฒŒ ์•Œ์•„๋ด…์‹œ๋‹ค.
๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ƒ์† ๊ด€๊ณ„๋ฅผ ๊ฐ€์ง„ ํด๋ž˜์Šค๋“ค์„ ์ •์˜ํ•ด์ค๋‹ˆ๋‹ค:
class A(): pass class B(A): pass class C(A): pass class D_0(B, C): pass class D_1(B, C): pass class E_0(D_0): pass class E_1(D_1): pass class F(E_0, E_1): pass
Python
๋ณต์‚ฌ
์œ„์˜ ์ƒ์†๊ด€๊ณ„๋ฅผ ๋„์‹ํ™” ํ•˜์—ฌ ํ‘œํ˜„ํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค:
F ํด๋ž˜์Šค์˜ MRO๋ฅผ ์ˆœ์ฐจ์ ์œผ๋กœ ์ถœ๋ ฅํ•ด๋ณด๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค:
print([x.__name__ for x in F.mro()])
Python
๋ณต์‚ฌ
['F', 'E_0', 'D_0', 'E_1', 'D_1', 'B', 'C', 'A', 'object']
Python
๋ณต์‚ฌ
์œ„์—์„œ ์„ค๋ช…ํ•œ ๋ฃฐ์— ๋”ฐ๋ผ F ์ธ์Šคํ„ด์Šค์—์„œ ์–ด๋–ค attribute๋‚˜ method๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด,
๋ณธ์ธ ํด๋ž˜์Šค(F)๋ฅผ ๋จผ์ € ํƒ์ƒ‰ํ•œ ๋’ค, ์ฒซ ๋ฒˆ์งธ ๋ถ€๋ชจ ํด๋ž˜์Šค๋ถ€ํ„ฐ ์ˆœ์ฐจ์ ์œผ๋กœ ๊นŠ์ด ์šฐ์„  ํƒ์ƒ‰์„ ์ง„ํ–‰ํ•ฉ๋‹ˆ๋‹ค:
['F', 'E_0', 'D_0', 'E_1', 'D_1', 'B', 'C', 'A', 'object']
Python
๋ณต์‚ฌ
D_0์™€ D_1์—์„œ ๊ณตํ†ต์œผ๋กœ ์ƒ์† ๋ฐ›์€ ๋ถ€๋ชจ ํด๋ž˜์Šค(B)๋ฅผ ๋งŒ๋‚˜๋ฉด, F์˜ ๋‘ ๋ฒˆ์งธ ๋ถ€๋ชจ ํด๋ž˜์Šค์ธ E_1๋ถ€ํ„ฐ ๋‹ค์‹œ ํƒ์ƒ‰์„ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค:
['F', 'E_0', 'D_0', 'E_1', 'D_1', 'B', 'C', 'A', 'object']
Python
๋ณต์‚ฌ
๋งˆ์ง€๋ง‰์œผ๋กœ ๊ณตํ†ต ๋ถ€๋ชจ์ธ B๋ถ€ํ„ฐ ํƒ์ƒ‰ํ•˜๋Š”๋ฐ ์ด ๋•Œ๋„ A๊ฐ€ ๊ณตํ†ต ๋ถ€๋ชจ์ด๊ธฐ ๋•Œ๋ฌธ์— ํƒ์ƒ‰ ์ˆœ์„œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค:
['F', 'E_0', 'D_0', 'E_1', 'D_1', 'B', 'C', 'A', 'object']
Python
๋ณต์‚ฌ
๋”ฐ๋ผ์„œ ํ˜„์žฌ ํด๋ž˜์Šค์— ์žˆ๋Š” attribute๋‚˜ method๊ฐ€ ์•„๋‹ˆ๋ฉด ์ƒ์† ๋ฐ›์€ ํด๋ž˜์Šค๋ฅผ ํƒ์ƒ‰ํ•  ๋•Œ ์™ผ์ชฝ์— ์žˆ๋Š” Mixin๋ถ€ํ„ฐ ํƒ์ƒ‰ํ•˜๊ณ  ๋งˆ์ง€๋ง‰์œผ๋กœ Base View๋ฅผ ํ™•์ธํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.
์šฐ๋ฆฌ๊ฐ€ Mixin์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ๊ธฐ์กด View์— ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•˜๊ธฐ ์œ„ํ•œ ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์— ํƒ์ƒ‰์„ ํ•  ๋•Œ๋„ BaseView ๋ณด๋‹ค๋Š” Mixin๋ฅผ ๋จผ์ € ํƒ์ƒ‰ํ•˜๋Š” ๊ฒƒ์ด ํ•ฉ๋ฆฌ์ ์ž…๋‹ˆ๋‹ค.
๋˜ ๊ฐ€๊ธ‰์  Mixin์€ ๋‹ค๋ฅธ Class๋กœ๋ถ€ํ„ฐ ์ƒ์†์„ ๋ฐ›์ง€ ์•Š์•„์„œ inheritance chain์„ ๋‹จ์ˆœํ•˜๊ฒŒ ์œ ์ง€ํ•จ์œผ๋กœ์„œ ์˜ˆ์ƒํ•˜์ง€ ๋ชปํ•œ ๊ฒฐ๊ณผ๋ฅผ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

References