Django

GreenBeanΒ·2022λ…„ 2μ›” 11일
0
post-thumbnail

Django

초보 μ›Ή ν”„λ‘œκ·Έλž˜λ¨Έ

Proxy Model

  • 닀쀑 ν…Œμ΄λΈ” 상속(Multi-table inheritance)을 μ‚¬μš©ν•˜λ©΄ λͺ¨λΈμ˜ 각 μžμ‹ ν΄λž˜μŠ€μ— λŒ€ν•΄ μƒˆ λ°μ΄ν„°λ² μ΄μŠ€ ν…Œμ΄λΈ”μ΄ λ§Œλ“€μ–΄μ§
    • μžμ‹ ν΄λž˜μŠ€λŠ” λΆ€λͺ¨ ν΄λž˜μŠ€μ—λŠ” μ—†λŠ” μΆ”κ°€ 데이터 ν•„λ“œλ₯Ό μ €μž₯ν•  μž₯μ†Œκ°€ ν•„μš” ν•˜κΈ° λ•Œλ¬Έμ— 일반적으둜 μ›ν•˜λŠ” λ™μž‘
    • ν•˜μ§€λ§Œ λ•Œλ‘œλŠ” 파이썬 μˆ˜μ€€μ˜ λ™μž‘λ§Œμ„ λ³€κ²½ ν•˜κ³  싢을 κ²½μš°λ„ 있음
      • κΈ°λ³Έ λ§€λ‹ˆμ €λ₯Ό λ³€κ²½ν•˜κ±°λ‚˜ λ©”μ„œλ“œλ₯Ό μΆ”κ°€ ν•˜λŠ” 정도
    • 예λ₯Ό λ“€μ–΄ μ‚¬μš©μž(μœ μ €) λͺ¨λΈμ„ λ§Œλ“€μ—ˆλŠ”λ° κ΄€λ¦¬μžμ™€ 일반 μœ μ €μ˜ 행동이 λ‹€λ₯Έ κ²½μš°μ— κ΄€λ¦¬μž λΆˆλ¦¬μ–Έ ν•„λ“œλ₯Ό ν•˜λ‚˜ μ£Όκ³  κ·Έ 값에 λ”°λΌμ„œ κΈ°λŠ₯을 μˆ˜ν–‰ ν•  수 μžˆμ§€λ§Œ ν΄λž˜μŠ€κ°€ λ„ˆλ¬΄ μ»€μ§€λ―€λ‘œ 효율적으둜 κΈ°λŠ₯만 뢄리 κ°€λŠ₯ ν•˜κ²Œ ν•˜λŠ” 것이 Proxy Model
  • ν…Œμ΄λΈ” μƒμ—λŠ” λ³€ν™”λŠ” μ—†μ§€λ§Œ νŒŒμ΄μ¬μ—μ„œ ν…Œμ΄λΈ”μ„ λ‹€λ£¨λŠ” λͺ¨λΈ(κ΄€λ¦¬μž, μŠ€νƒœν”„, μΌλ°˜μœ μ €)을 μ—¬λŸ¬κ°œ μ‚¬μš©ν•˜κ³  싢을 경우
    • μ›λž˜ λͺ¨λΈμ— λŒ€ν•œ ν”„λ‘μ‹œλ₯Ό λ§Œλ“œλ©΄ ν”„λ‘μ‹œ λͺ¨λΈμ˜ μΈμŠ€ν„΄μŠ€λ₯Ό 생성, μ‚­μ œ, μ—…λ°μ΄νŠΈλ₯Ό ν•  수 있으며 μ›λž˜ λͺ¨λΈμ„ μ‚¬μš©ν•˜λŠ”κ²ƒ 처럼 λͺ¨λ“  데이터가 μ €μž₯됨
    • 차이점은 원본을 λ³€κ²½ν•˜μ§€ μ•Šκ³  ν”„λ‘μ‹œμ˜ κΈ°λ³Έ λͺ¨λΈ μˆœμ„œ λ˜λŠ” κΈ°λ³Έ λ§€λ‹ˆμ €μ™€ 같은 것을 λ³€κ²½ ν•  수 μžˆλ‹€λŠ” 것
  • Meta Class에 Proxy=Trueλ₯Ό μ„€μ •ν•˜μ—¬ μ‚¬μš© ν•  수 있음
# μ˜ˆμ‹œ μ½”λ“œ
from django.db import models

__all__ = (
    'User',
    'Admin',
    'Staff',
)


class User(models.Model):
    name = models.CharField(max_length=50)
    is_admin = models.BooleanField(default=False)

    def __str__(self):
        return self.name


class Admin(User):
    class Meta:
        proxy = True

    def drop(self, user):
        user.delete()

    def __str__(self):
        return f'{self.name} (κ΄€λ¦¬μž)'


class Staff(User):
    class Meta:
        proxy = True

    def block(self, user):
        user.is_block = True
        user.save()

    def __str__(self):
        return f'{self.name} (μŠ€νƒœν”„)'
  • μ΄λ ‡κ²Œ κΈ°λŠ₯λ³„λ‘œ λ‚˜λˆ„μ–΄ μ‚¬μš©ν•˜λ©΄ μ‹€μˆ˜ν•  κ°€λŠ₯성을 많이 μ€„μΌμˆ˜ 있고 λ§€λ‹ˆμ €λ₯Ό λ”°λ‘œ 두어 관리 κ°€λŠ₯
# μ˜ˆμ‹œ μ½”λ“œ
from django.db.models.manager import Manager

class User(models.Model):
    ...
    is_staff = models.BooleanField(default=False)
    is_block = models.BooleanField(default=False)

...

class AdminManager(Manager):
    def get_queryset(self):
        return super().get_queryset().filter(is_admin=True)


class Admin(User):
    objects = AdminManager()
    ...
    

class StaffManager(Manager):
    def get_queryset(self):
        return super().get_queryset().filter(is_staff=True)
        
        
class Staff(User):
    objects = StaffManager()
    ...
  • μ΄λŸ°μ‹μœΌλ‘œ λ§Œλ“€λ©΄ get_query_set을 톡해 λ§€λ‹ˆμ €μ—μ„œ 기본적으둜 κ°€μ Έμ˜€λŠ” 쿼리셋을 λ³€κ²½ ν•  수 있음
    • 기본적으둜 전체 데이터λ₯Ό κ°€μ Έ μ˜€μ§€λ§Œ ν”„λ‘μ‹œ λͺ¨λΈμ— κΈ°λ³Έ λ§€λ‹ˆμ €λ₯Ό μž¬μ •μ˜ ν•˜μ—¬ 필터링을 ν•œ 것을 기본으둜 κ°€μ Έμ˜΄
  • ν”„λ‘μ‹œ λͺ¨λΈμ—μ„œλ„ Meta μ†μ„±μ˜ ordering 같은것을 μ‚¬μš©ν•  수 있으며 λ§€λ‹ˆμ €λ₯Ό μ—¬λŸ¬κ°œ 가지고 μžˆμ„ μˆ˜λ„ 있음
    • User 객체에 쿼리λ₯Ό ν•΄μ„œ Admin μ΄λ‚˜ Staff 객체λ₯Ό κΊΌλ‚΄λŠ” 것은 λΆˆκ°€λŠ₯
    • 이것은 κΈ°μ‘΄ λͺ¨λΈμ„ λŒ€μ²΄ν•˜λŠ” 것이 μ•„λ‹Œ λ‹€λ₯Έ ν˜•νƒœλ‘œ μ“°κΈ° μœ„ν•΄ μžˆλŠ” 방법
    • κ²°κ΅­ 같은 ν…Œμ΄λΈ”μ„ μ“°λŠ” λ‹€λ₯Έ ν΄λž˜μŠ€κ°€ λœλ‹€λŠ” 것
  • ν”„λ‘μ‹œ λͺ¨λΈμ„ μ •ν™•νžˆ ν•˜λ‚˜μ˜ λΉ„ 좔상적 λͺ¨λΈ 클래슀λ₯Ό 상속 해야함
    • ν”„λ‘μ‹œ λͺ¨λΈμ€ λ‹€λ₯Έ λ°μ΄ν„°λ² μ΄μŠ€ ν…Œμ΄λΈ”μ˜ ν–‰ 사이에 연결을 μ œκ³΅ν•˜μ§€ μ•ŠμœΌλ―€λ‘œ μ—¬λŸ¬ λΉ„ 좔상적 λͺ¨λΈμ„ 상속받을 수 μ—†μŒ
    • μ‹€μ œλ‘œ μ‘΄μž¬ν•˜λŠ” ν…Œμ΄λΈ”μ˜ λͺ¨λΈμ€ ν•˜λ‚˜λ§Œ 상속 받을 수 있으며 λ§Œμ•½ Abstract base class에 ν•„λ“œκ°€ μ•„λ‹Œ λ©”μ†Œλ“œλ§Œ μžˆμ„ κ²½μš°μ—λŠ” 상속을 받을 수 있음
    • μ‹€μ œ λͺ¨λΈμ„ 상속받은 ν”„λ‘μ‹œ λͺ¨λΈμ΄ 쑴재 ν•  경우 κ·Έ ν”„λ‘μ‹œ λͺ¨λΈμ„ λ‹€μ‹œ 상속 λ°›λŠ” ν˜•νƒœλ‘œλ„ κ°€λŠ₯
  • ν”„λ‘μ‹œ λͺ¨λΈμ— λͺ¨λΈ λ§€λ‹ˆμ €λ₯Ό μ§€μ •ν•˜μ§€ μ•ŠμœΌλ©΄ λͺ¨λΈ λΆ€λͺ¨λ‘œλΆ€ν„° λ§€λ‹ˆμ €λ₯Ό 상속 λ°›μŒ
    • ν”„λ‘μ‹œ λͺ¨λΈμ—μ„œ λ§€λ‹ˆμ €λ₯Ό μ •μ˜ ν•˜λ©΄ λΆ€λͺ¨ ν΄λž˜μŠ€μ— μ •μ˜ 된 λ§€λ‹ˆμ €λŠ” 꼐속 μ‚¬μš©ν•  수 μžˆμ§€λ§Œ 기본값이 됨
    • λ§Œμ•½ ν”„λ‘μ‹œ λͺ¨λΈμ— κΈ°λ³Έ λ§€λ„ˆμ§€λ₯Ό 바꾸지 μ•Šκ³  μƒˆ κ΄€λ¦¬μžλ₯Ό μΆ”κ°€ ν•˜λ €λ©΄ μƒˆ κ΄€λ¦¬μžλ₯Ό ν¬ν•¨ν•˜λŠ” κΈ°λ³Έ 클래슀λ₯Ό μž‘μ„±ν•˜κ³  κΈ°λ³Έ 클래슀 λ‹€μŒμ— 상속함

Tip! μΆ”κ°€ λ‚΄μš©

λ™μΌν•œ λͺ¨λΈμ— λŒ€ν•œ μ—¬λŸ¬ ModelAdmins

  • λ™μΌν•œ λͺ¨λΈμ— λŒ€ν•΄ λ‘˜ μ΄μƒμ˜ ModelAdmin을 μž‘μ„±ν•˜κ³  각각 λ‹€λ₯Έ λ°©μ‹μœΌλ‘œ μ‚¬μš©μž μ •μ˜ν•˜κ³  λ‹€λ₯Έ URL에 λ§ν¬ν•˜λŠ” 방법
    • Proxy Model을 μ‚¬μš©ν•˜μ—¬ 각 λͺ¨λΈμ΄ ν•œ 번만 등둝 될 수 μžˆλ‹€λŠ” 사싀을 극볡
# μ˜ˆμ‹œ μ½”λ“œ
class PostAdmin(admin.ModelAdmin):
    list_display = ('title', 'pubdate','user')

class MyPost(Post):
    class Meta:
        proxy = True

class MyPostAdmin(PostAdmin):
    def get_queryset(self, request):
        return self.model.objects.filter(user = request.user)


admin.site.register(Post, PostAdmin)
admin.site.register(MyPost, MyPostAdmin)

Tip! μΆ”κ°€ μ˜ˆμ‹œ

# μœ„ ꡬ문과 λ™μΌν•œ λ‚΄μš©
def create_modeladmin(modeladmin, model, name = None):
    class  Meta:
        proxy = True
        app_label = model._meta.app_label

    attrs = {'__module__': '', 'Meta': Meta}

    newmodel = type(name, (model,), attrs)

    admin.site.register(newmodel, modeladmin)
    return modeladmin
profile
🌱 Backend-Dev | hwaya2828@gmail.com

0개의 λŒ“κΈ€