๐Ÿ‘ฆ ๋‚ด์ผ๋ฐฐ์›€์บ ํ”„/TIL(Today I Learned)

TIL_220616_DRF ๊ฐ•์˜

  • -

DRF ๊ฐ•์˜ ๋ณธ๊ฒฉ์ ์œผ๋กœ ๋“ฃ๊ฒŒ ๋œ 3์ผ์ฐจ ๊ณผ์ •์˜ ๋‚ด์šฉ..

 

์–ด์šฐ.. ์ •์‹ ์„ ๋ชป์ฐจ๋ฆฐ๋‹ค.

 

์ƒ๊ฐ๋ณด๋‹ค ์‹ฌ์˜คํ•˜๊ณ  ๋”ฅํ•œ ์žฅ๊ณ ์˜ ์„ธ๊ณ„

 

๊ทธ๋ฆฌ๊ณ  ๋„ˆ๋ฌด ํŽธ๋ฆฌํ•œ ๊ธฐ๋Šฅ์„๋“ค ์–ด๋–ป๊ฒŒ๋“  ํ™œ์šฉํ•˜๊ธฐ ์œ„ํ•œ ๋ฐœ๋ฒ„๋‘ฅ..

 

๋‚ด๊ฐ€ ์ด ๋ชจ๋“  ๊ธฐ๋Šฅ๋“ค์„ ์ž˜ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ์„๊นŒ..

 

 

๋‚˜ ์ž์‹  ํ™”์ดํŒ…..

 


 

์—๋Ÿฌ ๋…ธํŠธ

์‚ฌ์‹ค ์—๋Ÿฌ๋ผ๊ธฐ ๋ณด๋‹ค๋Š” ๋‚ด๊ฐ€ ์‹ค์ˆ˜ํ•œ ๋‚ด์šฉ์ด์ง€๋งŒ, ๋‘ ๋ฒˆ ์‹ค์ˆ˜ํ•˜์ง€ ์•Š๊ธฐ ์œ„ํ•ด ์ ์–ด๋‘”๋‹ค.

 

<ํฌ์ŠคํŠธ๋งจ ์—๋Ÿฌ>
์›์ธ : TypeError: Cannot read properties of undefined (reading 'value')

๋‚ด์šฉ : ํฌ์ŠคํŠธ๋งจ <send> ์‹œ ๋ฐœ์ƒํ•˜๋Š” ์—๋Ÿฌ
ํ•ด๊ฒฐ : path('login/', views."UserAPIView".as_view()),

๋‚ด์šฉ : urls.py ์˜ ๊ฒฝ๋กœ์— ์žˆ๋˜ ํด๋ž˜์Šค ๋ช… ์˜คํƒ€๋กœ ์ธํ•œ ์—๋Ÿฌ

 


 

3์ผ์ฐจ ๊ณผ์ œ

1. Django ํ”„๋กœ์ ํŠธ๋ฅผ ์ƒ์„ฑํ•˜๊ณ , user ๋ผ๋Š” ์•ฑ์„ ๋งŒ๋“ค์–ด์„œ settings.py ์— ๋“ฑ๋กํ•ด๋ณด์„ธ์š”.

INSTALLED_APPS = [
    'user',
]

 

2. user/models.py์— `Custom user model`์„ ์ƒ์„ฑํ•œ ํ›„ django์—์„œ user table์„ ์ƒ์„ฑ ํ•œ ๋ชจ๋ธ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ์„ค์ •ํ•ด์ฃผ์„ธ์š”

# custom user model
class User(AbstractBaseUser):
    # unique=True ์„ค์ •์œผ๋กœ ์ค‘๋ณต๊ฐ’์„ ๋ฐฉ์ง€
    username = models.CharField("์‚ฌ์šฉ์ž ๊ณ„์ •", max_length=50, unique=True)
    # ํŒจ์Šค์›Œ๋“œ๋Š” ์•”ํ˜ธํ™”๋˜์–ด ์ €์žฅ๋˜๊ธฐ ๋•Œ๋ฌธ์— max_length๋ฅผ ๋„‰๋„‰ํ•˜๊ฒŒ ์„ค์ •
    password = models.CharField("์‚ฌ์šฉ์ž ๋น„๋ฐ€๋ฒˆํ˜ธ", max_length=200)
    email = models.EmailField("์‚ฌ์šฉ์ž ์ด๋ฉ”์ผ", max_length=254)
    fullname = models.CharField("์‚ฌ์šฉ์ž ์ด๋ฆ„", max_length=20)
    join_date = models.DateField("๊ฐ€์ž…์ผ", auto_now_add=True)
    
    # ์‚ฌ์šฉ์ž ๊ณ„์ •์˜ ํ™œ์„ฑํ™” ์—ฌ๋ถ€ ํ™•์ธ
    is_active = models.BooleanField(default=True)
    
    # is_staff ์—์„œ ํ•ด๋‹น ๊ฐ’ ์‚ฌ์šฉ
    is_admin = models.BooleanField(default=False)

    # username ์„ ์•„์ด๋””๋กœ ์‚ฌ์šฉํ•˜๊ฒ ๋‹ค.
    USERNAME_FIELD = 'username'

    ''' user๋ฅผ ์ƒ์„ฑํ•  ๋•Œ ์ž…๋ ฅ๋ฐ›์€ ํ•„๋“œ ์ง€์ •
    ์‚ฌ์šฉํ•  ์ผ์ด ๊ฑฐ์˜ ์—†์Œ '''
    REQUIRED_FIELDS = []

    # custom user ์ƒ์„ฑ ์‹œ ํ•„์š”
    objects = UserManager()

    def __str__(self):
        return self.username

    # ์•„~ ์ด๋Ÿฐ๊ฒŒ ์žˆ๊ตฌ๋‚˜ ์ƒ๊ฐํ•˜๊ธฐ

    # ๋กœ๊ทธ์ธ ์‚ฌ์šฉ์ž์˜ ํŠน์ • ํ…Œ์ด๋ธ”์˜ crud ๊ถŒํ•œ์„ ์„ค์ •, perm table์˜ crud ๊ถŒํ•œ์ด ๋“ค์–ด๊ฐ„๋‹ค.
    # admin์ผ ๊ฒฝ์šฐ ํ•ญ์ƒ True, ๋น„ํ™œ์„ฑ ์‚ฌ์šฉ์ž(is_active=False)์˜ ๊ฒฝ์šฐ ํ•ญ์ƒ False
    def has_perm(self, perm, obj=None):
        return True

    # ๋กœ๊ทธ์ธ ์‚ฌ์šฉ์ž์˜ ํŠน์ • app์— ์ ‘๊ทผ ๊ฐ€๋Šฅ ์—ฌ๋ถ€๋ฅผ ์„ค์ •, app_label์—๋Š” app ์ด๋ฆ„์ด ๋“ค์–ด๊ฐ„๋‹ค.
    # admin์ผ ๊ฒฝ์šฐ ํ•ญ์ƒ True, ๋น„ํ™œ์„ฑ ์‚ฌ์šฉ์ž(is_active=False)์˜ ๊ฒฝ์šฐ ํ•ญ์ƒ False
    def has_module_perms(self, app_label):
        return True

    # admin ๊ถŒํ•œ ์„ค์ •
    @property
    def is_staff(self):
        return self.is_admin


3. user/models.py์— ์‚ฌ์šฉ์ž์˜ ์ƒ์„ธ ์ •๋ณด๋ฅผ ์ €์žฅํ•  ์ˆ˜ ์žˆ๋Š” `UserProfile` ์ด๋ผ๋Š” ๋ชจ๋ธ์„ ์ƒ์„ฑํ•ด์ฃผ์„ธ์š”

class UserProfile(models.Model):
    user = models.OneToOneField(User, verbose_name="์‚ฌ์šฉ์ž", on_delete=models.CASCADE)
    introduction = models.TextField("์ž๊ธฐ์†Œ๊ฐœ", null=True, blank=True)
    birthday = models.DateField("์ƒ์ผ")
    age = models.IntegerField("๋‚˜์ด")
    hobby = models.ManyToManyField(Hobby, verbose_name="์ทจ๋ฏธ")

    def __str__(self):
        return f"{self.user.username} ๋‹˜์˜ ํ”„๋กœํ•„์ž…๋‹ˆ๋‹ค."

# user - user detail : 1:1
# ํ•œ ์œ ์ €๊ฐ€ ๋‘ ํ”„๋กœํ•„์„ ๊ฐ€์งˆ ์ˆ˜๋Š” ์—†์Œ !!!! (OneToOneField)

# ์ฟผ๋ฆฌ๋ฅผ ๋‚ ๋ ค์„œ crud๋ฅผ ํ•œ๋‹ค


4. blog๋ผ๋Š” ์•ฑ์„ ๋งŒ๋“  ํ›„ settings.py์— ๋“ฑ๋กํ•ด์ฃผ์„ธ์š”

INSTALLED_APPS = [
    'blog',
]


5. blog/models.py์— <์นดํ…Œ๊ณ ๋ฆฌ ์ด๋ฆ„, ์„ค๋ช…>์ด ๋“ค์–ด๊ฐˆ ์ˆ˜ ์žˆ๋Š” `Category`๋ผ๋Š” ๋ชจ๋ธ์„ ๋งŒ๋“ค์–ด๋ณด์„ธ์š”.

class Category(models.Model):
    name = models.CharField("์‚ฌ์šฉ์ž ์ด๋ฆ„", max_length=50)
    description = models.TextField("์„ค๋ช…")

    def __str__(self):
        return self.name


6. blog/models.py์— <๊ธ€ ์ž‘์„ฑ์ž, ๊ธ€ ์ œ๋ชฉ, ์นดํ…Œ๊ณ ๋ฆฌ, ๊ธ€ ๋‚ด์šฉ>์ด ๋“ค์–ด๊ฐˆ ์ˆ˜ ์žˆ๋Š” `Article` ์ด๋ผ๋Š” ๋ชจ๋ธ์„ ๋งŒ๋“ค์–ด๋ณด์„ธ์š”.(์นดํ…Œ๊ณ ๋ฆฌ๋Š” 2๊ฐœ ์ด์ƒ ์„ ํƒํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•ด์š”)

# ManyToManyField

class Article(models.Model):
    user = models.ForeignKey('user.User', verbose_name="๊ธ€ ์ž‘์„ฑ์ž", on_delete=models.CASCADE)
    title = models.CharField("๊ธ€ ์ œ๋ชฉ", max_length=50)
    content = models.TextField("๊ธ€ ๋ณธ๋ฌธ")
    category = models.ManyToManyField(Category, verbose_name="์นดํ…Œ๊ณ ๋ฆฌ")
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    
    def __str__(self):
        return f"{self.user.username} ๋‹˜์ด ์ž‘์„ฑํ•˜์‹  ๊ธ€์ž…๋‹ˆ๋‹ค."

 

7. Article ๋ชจ๋ธ์—์„œ ์™ธ๋ž˜ ํ‚ค๋ฅผ ํ™œ์šฉํ•ด์„œ ์ž‘์„ฑ์ž์™€ ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๊ด€๊ณ„๋ฅผ ๋งบ์–ด์ฃผ์„ธ์š”

# ForeignKey

# ์ž‘์„ฑ์ž์˜ ๊ด€๊ณ„
user = models.ForeignKey('user.User', verbose_name="๊ธ€ ์ž‘์„ฑ์ž", on_delete=models.CASCADE)

# ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๊ด€๊ณ„
category = models.ManyToManyField(Category, verbose_name="์นดํ…Œ๊ณ ๋ฆฌ")

 

8. admin.py์— ๋งŒ๋“ค์—ˆ๋˜ ๋ชจ๋ธ๋“ค์„ ์ถ”๊ฐ€ํ•ด ์‚ฌ์šฉ์ž์™€ ๊ฒŒ์‹œ๊ธ€์„ ์ž์œ ๋กญ๊ฒŒ ์ƒ์„ฑ, ์ˆ˜์ • ํ•  ์ˆ˜ ์žˆ๋„๋ก ์„ค์ •ํ•ด์ฃผ์„ธ์š”

from django.contrib import admin
from blog.models import Category, Article

# Register your models here.
admin.site.register(Category)
admin.site.register(Article)

 

9.  CBV ๊ธฐ๋ฐ˜์œผ๋กœ ๋กœ๊ทธ์ธ / ๋กœ๊ตฌ์•„์›ƒ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•ด์ฃผ์„ธ์š”

from django.contrib.auth import login, logout, authenticate

class UserAPIView(APIView):
    # permission_classes = [permissions.AllowAny]
    
    # ๋กœ๊ทธ์ธ
    def post(self, request):
        username = request.data.get('username', '')
        password = request.data.get('password', '')

        user = authenticate(request, username=username, password=password)

        if not user:
            return Response({"error": "์กด์žฌํ•˜์ง€ ์•Š๋Š” ๊ณ„์ •์ด๊ฑฐ๋‚˜ ํŒจ์Šค์›Œ๋“œ๊ฐ€ ์ผ์น˜ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค."})

        login(request, user)
        return Response({"message": "login success!"})

    def delete(self, request):
        logout(request)
        return Response({"message": "logout success!"})



10.   CBV ๊ธฐ๋ฐ˜์œผ๋กœ ๋กœ๊ทธ์ธ ํ•œ ์‚ฌ์šฉ์ž์˜ ๊ฒŒ์‹œ๊ธ€์˜ ์ œ๋ชฉ์„ ๋ฆฌํ„ดํ•ด์ฃผ๋Š” ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•ด์ฃผ์„ธ์š”

def __str__(self):
    return f"{self.user.username} ๋‹˜์ด ์ž‘์„ฑํ•˜์‹  ๊ธ€์ž…๋‹ˆ๋‹ค."
 

 

Contents

ํฌ์ŠคํŒ… ์ฃผ์†Œ๋ฅผ ๋ณต์‚ฌํ–ˆ์Šต๋‹ˆ๋‹ค

์ด ๊ธ€์ด ๋„์›€์ด ๋˜์—ˆ๋‹ค๋ฉด ๊ณต๊ฐ ๋ถ€ํƒ๋“œ๋ฆฝ๋‹ˆ๋‹ค.