Skip to content
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

Update views.py #2

Open
wants to merge 15 commits into
base: main
Choose a base branch
from
Open
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
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
2021-05-03 ~
Empty file added comments/__init__.py
Empty file.
4 changes: 4 additions & 0 deletions comments/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from django.contrib import admin
from .models import Comment

admin.site.register(Comment)
6 changes: 6 additions & 0 deletions comments/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from django.apps import AppConfig


class CommentsConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'comments'
30 changes: 30 additions & 0 deletions comments/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Generated by Django 3.2 on 2021-05-04 06:14

from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

initial = True

dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('webtoons', '0001_initial'),
]

operations = [
migrations.CreateModel(
name='Comment',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('contents', models.TextField()),
('created_at', models.DateTimeField(auto_now_add=True)),
('likes', models.PositiveIntegerField()),
('dislikes', models.PositiveIntegerField()),
('episode_info', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='webtoons.episode')),
('writer', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
),
]
Empty file added comments/migrations/__init__.py
Empty file.
13 changes: 13 additions & 0 deletions comments/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from django.db import models
from webtoons.models import Episode

class Comment(models.Model):
episode_info = models.ForeignKey(Episode, on_delete=models.CASCADE)
writer = models.ForeignKey("auth.User", on_delete=models.CASCADE)
contents = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
likes = models.PositiveIntegerField()
dislikes = models.PositiveIntegerField()

def __str__(self):
return self.contents
7 changes: 7 additions & 0 deletions comments/permissions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from rest_framework import permissions

class IsWriterOrReadOnly(permissions.BasePermission):
def has_object_permission(self, request, view, obj):
if request.method in permissions.SAFE_METHODS:
return True
return obj.writer == request.user
11 changes: 11 additions & 0 deletions comments/serializers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from rest_framework import serializers

from .models import Comment

class CommentSerializer(serializers.ModelSerializer):
episode_info = serializers.ReadOnlyField(source='episode_info.title')
writer = serializers.ReadOnlyField(source='writer.username')
class Meta:
model = Comment
fields = ['id', 'episode_info', 'writer', 'contents', 'created_at', 'likes', 'dislikes']

3 changes: 3 additions & 0 deletions comments/tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from django.test import TestCase

# Create your tests here.
8 changes: 8 additions & 0 deletions comments/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from django.urls import path

from . import views

urlpatterns = [
path('', views.CommentList.as_view()),
path('<int:comment_id>/', views.CommentDetail.as_view()),
]
42 changes: 42 additions & 0 deletions comments/views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
from django.shortcuts import get_object_or_404

from rest_framework import status
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework import permissions

from .models import Comment
from .serializers import CommentSerializer
from .permissions import IsWriterOrReadOnly

class CommentList(APIView):
permission_classes = [permissions.IsAuthenticatedOrReadOnly]

def get(self, request, webtoon_id, episode_id, format=None):
comments = Comment.objects.filter(episode_info_id=episode_id).order_by('-created_at')
serializer = CommentSerializer(comments, many=True)
return Response(serializer.data)

def post(self, request, webtoon_id, episode_id, format=None):
serializer = CommentSerializer(data=request.data)
if serializer.is_valid():
serializer.save(episode_info_id=episode_id, writer=request.user)
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

class CommentDetail(APIView):
permission_classes = [permissions.IsAuthenticatedOrReadOnly, IsWriterOrReadOnly]

def get_object(self, webtoon_id, episode_id, comment_id):
return get_object_or_404(Comment, pk=comment_id, episode_info_id=episode_id)

def get(self, request, webtoon_id, episode_id, comment_id, format=None):
comment = self.get_object(webtoon_id, episode_id, comment_id)
serializer = CommentSerializer(comment)
return Response(serializer.data)

def delete(self, request, webtoon_id, episode_id, comment_id, format=None):
comment = self.get_object(webtoon_id, episode_id, comment_id)
comment.delete()
return Response(status=status.HTTP_204_NO_CONTENT)

Binary file added conf/media/default_episode_image.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added conf/media/default_thumnail_image.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 8 additions & 1 deletion conf/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,13 @@
'django.contrib.staticfiles',
'django_extensions',
'rest_framework',
'drf_yasg',
]

PROJECT_APPS = [

'webtoons.apps.WebtoonsConfig',
'comments.apps.CommentsConfig',
'interests.apps.InterestsConfig',
]

INSTALLED_APPS = DJANGO_APPS + PROJECT_APPS
Expand Down Expand Up @@ -128,6 +131,10 @@

STATIC_URL = '/static/'

# Media files
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

# Default primary key field type
# https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field

Expand Down
42 changes: 26 additions & 16 deletions conf/urls.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,31 @@
"""conf URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/3.2/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path
from django.urls import path, include, re_path
from rest_framework import permissions
from drf_yasg.views import get_schema_view
from drf_yasg import openapi

schema_view = get_schema_view(
openapi.Info(
title="webtoon API",
default_version="v1",
description="naver webtoon 어플리케이션 주요 기능의 요구사항을 분석하여 만든 webtoon API 문서",
terms_of_service="https://www.google.com/policies/terms/",
contact=openapi.Contact(name="test", email="[email protected]"),
license=openapi.License(name="Test License"),
),
public=True,
permission_classes=(permissions.AllowAny,),
)

urlpatterns = [
path('api-auth/', include('rest_framework.urls')),
path('admin/', admin.site.urls),
path('v1.0/webtoons/', include('webtoons.urls')),
path('v1.0/interests/', include('interests.urls')),
]

urlpatterns += [
re_path(r'^swagger(?P<format>\.json|\.yaml)$', schema_view.without_ui(cache_timeout=0), name="schema-json"),
re_path(r'^swagger/$', schema_view.with_ui('swagger', cache_timeout=0), name='schema-swagger-ui'),
re_path(r'^redoc/$', schema_view.with_ui('redoc', cache_timeout=0), name='schema-redoc'),
]
Empty file added interests/__init__.py
Empty file.
4 changes: 4 additions & 0 deletions interests/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from django.contrib import admin
from .models import Interest

admin.site.register(Interest)
6 changes: 6 additions & 0 deletions interests/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from django.apps import AppConfig


class InterestsConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'interests'
26 changes: 26 additions & 0 deletions interests/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Generated by Django 3.2 on 2021-05-04 06:14

from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

initial = True

dependencies = [
('webtoons', '0001_initial'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]

operations = [
migrations.CreateModel(
name='Interest',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('interest_webtoon_list', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='webtoons.webtoon')),
('owner', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
),
]
20 changes: 20 additions & 0 deletions interests/migrations/0002_alter_interest_interest_webtoon_list.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Generated by Django 3.2 on 2021-05-06 10:15

from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

dependencies = [
('webtoons', '0004_alter_episode_options'),
('interests', '0001_initial'),
]

operations = [
migrations.AlterField(
model_name='interest',
name='interest_webtoon_list',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='webtoons.webtoon', unique=True),
),
]
20 changes: 20 additions & 0 deletions interests/migrations/0003_alter_interest_interest_webtoon_list.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Generated by Django 3.2 on 2021-05-06 10:19

from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

dependencies = [
('webtoons', '0004_alter_episode_options'),
('interests', '0002_alter_interest_interest_webtoon_list'),
]

operations = [
migrations.AlterField(
model_name='interest',
name='interest_webtoon_list',
field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='webtoons.webtoon'),
),
]
20 changes: 20 additions & 0 deletions interests/migrations/0004_alter_interest_interest_webtoon_list.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Generated by Django 3.2 on 2021-05-06 10:30

from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

dependencies = [
('webtoons', '0004_alter_episode_options'),
('interests', '0003_alter_interest_interest_webtoon_list'),
]

operations = [
migrations.AlterField(
model_name='interest',
name='interest_webtoon_list',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='webtoons.webtoon', unique=True),
),
]
20 changes: 20 additions & 0 deletions interests/migrations/0005_alter_interest_interest_webtoon_list.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Generated by Django 3.2 on 2021-05-06 10:31

from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

dependencies = [
('webtoons', '0004_alter_episode_options'),
('interests', '0004_alter_interest_interest_webtoon_list'),
]

operations = [
migrations.AlterField(
model_name='interest',
name='interest_webtoon_list',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='webtoons.webtoon'),
),
]
Empty file.
9 changes: 9 additions & 0 deletions interests/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from django.db import models
from webtoons.models import Webtoon

class Interest(models.Model):
owner = models.ForeignKey("auth.User", on_delete=models.CASCADE)
interest_webtoon_list = models.ForeignKey(Webtoon, on_delete=models.CASCADE)

def __str__(self):
return self.interest_webtoon_list.title
13 changes: 13 additions & 0 deletions interests/permissions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from rest_framework import permissions

class IsOwnerOrReadOnly(permissions.BasePermission):
def has_object_permission(self, request, view, obj):
if request.method in permissions.SAFE_METHODS:
return True
return obj.owner == request.user

class IsOwner(permissions.BasePermission):
def has_object_permission(self, request, view, obj):
if request.method in permissions.SAFE_METHODS:
return True
return obj.owner == request.user
16 changes: 16 additions & 0 deletions interests/serializers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from rest_framework import serializers

from .models import Interest

class InterestSerializer(serializers.ModelSerializer):
owner = serializers.ReadOnlyField(source='owner.username')
class Meta:
model = Interest
fields = ['id', 'owner', 'interest_webtoon_list']

class InterestDetailSerializer(serializers.ModelSerializer):
owner = serializers.ReadOnlyField(source='owner.username')
interest_webtoon_list = serializers.ReadOnlyField(source='interest_webtoon_list.title')
class Meta:
model = Interest
fields = ['id', 'owner', 'interest_webtoon_list']
3 changes: 3 additions & 0 deletions interests/tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from django.test import TestCase

# Create your tests here.
8 changes: 8 additions & 0 deletions interests/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from django.urls import path

from . import views

urlpatterns = [
path('', views.InterestList.as_view()),
path('<int:interest_id>/', views.InterestDetail.as_view()),
]
Loading