💡 AI 인사이트

🤖 AI가 여기에 결과를 출력합니다...

댓글 커뮤니티

쿠팡이벤트

이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.

검색

    [코담] 웹개발·실전 프로젝트·AI까지, 파이썬·장고의 모든것을 담아낸 강의와 개발 노트

    전체 흐름 Part4 | ✅저자: 이유정(박사)

    소스보기

    모델에 사용자 연결 Snippet 모델 필드 추가 + .save() 오버라이드 snippets/models.py

    from django.contrib.auth.models import User
    from pygments.lexers import get_lexer_by_name
    from pygments.formatters.html import HtmlFormatter
    from pygments import highlight
    
    class Snippet(models.Model):
        # ... 기존 필드 생략 ...
        
        # 새로 추가된 필드
        owner = models.ForeignKey(User, related_name='snippets', on_delete=models.CASCADE)
        highlighted = models.TextField()
    
    	# 코드 저장 시 자동으로 하이라이트 처리
        def save(self, *args, **kwargs):
            lexer = get_lexer_by_name(self.language)
            linenos = 'table' if self.linenos else False
            options = {'title': self.title} if self.title else {}
            formatter = HtmlFormatter(style=self.style, linenos=linenos, full=True, **options)
            self.highlighted = highlight(self.code, lexer, formatter)
            super().save(*args, **kwargs)
    

    마이그레이션 (초기화 방식으로)

    rm -f db.sqlite3
    rm -r snippets/migrations
    python manage.py makemigrations snippets
    python manage.py migrate
    python manage.py createsuperuser  # 테스트 사용자 생성
    

    owner 필드 추가, UserSerializer 추가 snippets/serializers.py

    from rest_framework import serializers
    from snippets.models import Snippet
    from django.contrib.auth.models import User
    
    class SnippetSerializer(serializers.ModelSerializer):
    	# ... 기존 필드 생략 ...
        owner = serializers.ReadOnlyField(source='owner.username')
    	highlighted = serializers.ReadOnlyField() # 두개 필드추가
    
        class Meta:
            model = Snippet
            fields = ['id', 'title', 'code', 'linenos', 'language', 'style', 'owner', 'highlighted'] # owner, highlighted두개 필드 추가
    
    # owner 사용자 API뷰 추가
    class UserSerializer(serializers.ModelSerializer):
        snippets = serializers.PrimaryKeyRelatedField(many=True, queryset=Snippet.objects.all())
    
        class Meta:
            model = User
            fields = ['id', 'username', 'snippets']
    

    SnippetSerializer에 추가:

    owner = serializers.ReadOnlyField(source='owner.username')
    highlighted = serializers.ReadOnlyField()
    
    	model = Snippet
            fields = ['owner', 'highlighted']
    

    snippets/permissions.py (신규 파일 생성)

    from rest_framework import permissions
    
    class IsOwnerOrReadOnly(permissions.BasePermission):
        def has_object_permission(self, request, view, obj):
    	    # 읽기 요청이면 (GET, HEAD, OPTIONS)
            if request.method in permissions.SAFE_METHODS:
                return True
            # 수정/삭제 요청이면: 객체의 소유자만 가능
            return obj.owner == request.user
    
    • 사용자 A는 자신의 글만 수정/삭제하고
    • 사용자 B는 A의 글을 읽기만 가능하게 하려면
    • 이 권한 클래스가 필요합니다.

    views.py – 권한, 사용자 뷰, perform_create 추가

    from rest_framework import generics, permissions
    from snippets.models import Snippet
    from snippets.serializers import SnippetSerializer, UserSerializer
    from snippets.permissions import IsOwnerOrReadOnly
    from django.contrib.auth.models import User
    
    class SnippetList(generics.ListCreateAPIView):
        queryset = Snippet.objects.all()
        serializer_class = SnippetSerializer
        
        # 권한 추가
        permission_classes = [permissions.IsAuthenticatedOrReadOnly]
    
        def perform_create(self, serializer):
            serializer.save(owner=self.request.user)
    
    class SnippetDetail(generics.RetrieveUpdateDestroyAPIView):
        queryset = Snippet.objects.all()
        serializer_class = SnippetSerializer
        
        # 권한 추가
        permission_classes = [permissions.IsAuthenticatedOrReadOnly, IsOwnerOrReadOnly]
    
    # 사용자용 뷰 추가
    class UserList(generics.ListAPIView):
        queryset = User.objects.all()
        serializer_class = UserSerializer
    
    class UserDetail(generics.RetrieveAPIView):
        queryset = User.objects.all()
        serializer_class = UserSerializer
    

    snippets/urls.py

    from django.urls import path
    from snippets import views
    
    urlpatterns = [
        path('snippets/', views.SnippetList.as_view()),
        path('snippets/<int:pk>/', views.SnippetDetail.as_view()),
        path('users/', views.UserList.as_view()),
        path('users/<int:pk>/', views.UserDetail.as_view()),
    ]
    

    프로젝트 루트 tutorial/urls.py

    from django.contrib import admin
    from django.urls import path, include
    
    urlpatterns = [
        path("admin/", admin.site.urls),
        path("", include("snippets.urls")),
        path("api-auth/", include("rest_framework.urls")),  # 추가
    ]
    
    TOP
    preload preload