Skip to content

Feature: Add sponser viewset #14

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Feb 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion pyconkr/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@
from django.contrib import admin
from django.urls import include, path

import sponsor.routers

urlpatterns = [
path("api-auth/", include("rest_framework.urls")),
path("summernote/", include("django_summernote.urls")),
path("admin/", admin.site.urls),
path("sponsors/", include("sponsor.urls")),
path("sponsors/", include(sponsor.routers.get_router().urls)),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

]
17 changes: 17 additions & 0 deletions sponsor/permissions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from rest_framework import permissions

from sponsor.models import Sponsor


class IsOwnerOrReadOnly(permissions.BasePermission):
# https://stackoverflow.com/questions/72691826/djnago-rest-framework-how-to-allow-only-update-user-own-content-only
def has_object_permission(self, request, view, obj: Sponsor):
if request.method in permissions.SAFE_METHODS:
return True

return obj.manager_id == request.user or obj.creator == request.user
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

말씀 주신 커스텀 퍼미션 이군요! 👍

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

값을 바꾸지 않는 methods 일 때, 또는 매니저 또는 작성자가 접근할 때에만 Permission이 부여되는 커스텀 퍼미션이군요. 확인했습니다.



class OwnerOnly(permissions.BasePermission):
def has_object_permission(self, request, view, obj: Sponsor):
return obj.manager_id == request.user or obj.creator == request.user
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

관리자가 creatormanager 둘 다 있었네요 👍

10 changes: 10 additions & 0 deletions sponsor/routers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from rest_framework.routers import DefaultRouter

from sponsor.viewsets import *


def get_router():
router = DefaultRouter()
router.register("", SponsorViewSet, basename="sponsor")

return router
23 changes: 23 additions & 0 deletions sponsor/serializers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from rest_framework.serializers import ModelSerializer

from sponsor.models import Sponsor


class SponsorSerializer(ModelSerializer):
class Meta:
model = Sponsor
fields = "__all__"


class SponsorListSerializer(ModelSerializer):
class Meta:
model = Sponsor
fields = [
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

"name",
"level",
"desc",
"eng_desc",
"url",
"logo_image",
"id",
]
47 changes: 47 additions & 0 deletions sponsor/viewsets.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
from django.shortcuts import get_object_or_404
from rest_framework.permissions import IsAuthenticatedOrReadOnly
from rest_framework.response import Response
from rest_framework.viewsets import ModelViewSet

from sponsor.models import Sponsor
from sponsor.permissions import IsOwnerOrReadOnly, OwnerOnly
from sponsor.serializers import SponsorListSerializer, SponsorSerializer
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍



class SponsorViewSet(ModelViewSet):
serializer_class = SponsorSerializer
permission_classes = [IsOwnerOrReadOnly] # 본인 소유만 수정가능
http_method_names = ["get", "post"] # 지금은 조회/등록만 가능 TODO: 추후 수정기능 추가

def get_queryset(self):
return Sponsor.objects.all()

def list(self, request, *args, **kwargs):
queryset = Sponsor.objects.filter(accepted=True).order_by("name")
serializer = SponsorListSerializer(queryset, many=True)
return Response(serializer.data)

def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
serializer.save()
return Response(serializer.data)

def retrieve(self, request, *args, **kwargs):
pk = kwargs["pk"]
sponsor_data = get_object_or_404(Sponsor, pk=pk)

# 본인 소유인 경우는 모든 필드
# 그렇지 않은 경우는 공개 가능한 필드만 응답
serializer = (
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

와! 이렇게 작성이 가능하군요. 👍

SponsorSerializer(sponsor_data)
if self.check_owner_permission(request, sponsor_data)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

단순한 호기심이 있다면 🤔
해당 코드에서 not을 사용하지 않고 else로 처리한건 관용적으로 사용하는 부분이 있는지 궁금하네요 :)

else SponsorListSerializer(sponsor_data)
)

return Response(serializer.data)

def check_owner_permission(self, request, sponsor_data: Sponsor):
return OwnerOnly.has_object_permission(
self=OwnerOnly, request=request, view=self, obj=sponsor_data
)