댓글 API

  • url로 보낸 id 값을 받아야 한다.
  • 댓글을 조회하면 user는 email
  • todo는 title을 보여준다.

 

 

(app - models.py) 추가하기

class Comment(models.Model):
    user = models.ForeignKey(Users, on_delete=models.CASCADE)
    a_todo = models.ForeignKey(Todos, on_delete=models.CASCADE)
    content = models.CharField(max_length=256)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    def __str__(self):
        return str(self.content)

 

 

(app - urls.py) 추가하기

urlpatterns = [
    path('<int:todo_id>/comment/', views.CommentView.as_view(), name='comment_view'),
    path('<int:todo_id>/comment/<int:comment_id>/', views.CommentDetailView.as_view(), name='comment_detail_view'),
]

 

 

(app - serializers.py)

class CommentSerialize(serializers.ModelSerializer):
    #시리얼라이저에서 메서드를 호출하여 필드의 값을 결정한다
    user = serializers.SerializerMethodField()
    todo = serializers.SerializerMethodField()
    
    #여기 메서드 호출
    def get_user(self, obj):
        return obj.user.email
    
    def get_todo(self, obj):
        return obj.a_todo.title
    
    class Meta:
        model = Comment
        # a_todo를 뺀 나머지 필드
        exclude = ('a_todo', )

class CommentCreateSerialize(serializers.ModelSerializer):
    class Meta:
        model = Comment
        fields = ['content', ]


class TodoSerialize(serializers.ModelSerializer):
    # 추가하기
    # 역참조
    # todo 게시글에서도 comment를 보여줌
    comment_set = CommentSerialize(many = True)

 

 

(app - views.py)

class CommentView(APIView):
    permission_classes = [IsAuthenticated]

    def get(self, request, todo_id):
        comment = Comment.objects.all()
        serialize = CommentSerialize(comment, many=True)
        return Response(serialize.data, status=status.HTTP_200_OK)
    
    def post(self, request, todo_id):
        serialize = CommentCreateSerialize(data=request.data)
        todo = Todos(id=todo_id)
        if serialize.is_valid():
            serialize.save(user=request.user, a_todo=todo)
            return Response(serialize.data, status=status.HTTP_201_CREATED)
        else:
            return Response(f'${serialize.errors}', status=status.HTTP_400_BAD_REQUEST)

class CommentDetailView(APIView):
    permission_classes = [IsAuthenticated]

    def put(self, request, todo_id, comment_id):
        comment = get_object_or_404(Comment, id=comment_id)
        if request.user == comment.user:
            serialize = CommentSerialize(comment, data=request.data)
            if serialize.is_valid():
                serialize.save()
                return Response({"수정됨":serialize.data}, status=status.HTTP_200_OK)
        else:
            return Response({'message':'권한이 없습니다'},status=status.HTTP_400_BAD_REQUEST)
    
    def delete(self, request, todo_id, comment_id):
        comment = get_object_or_404(Comment, id=comment_id)
        if request.user == comment.user:
            comment.delete()
            return Response('댓글 삭제 완료', status=status.HTTP_204_NO_CONTENT)
        else:
            return Response({'message':'권한이 없습니다'},status=status.HTTP_400_BAD_REQUEST)

 

 

Todo 리스트

  • 게시글을 전부 불러와 보여질 페이지
  • 여러개의 시리얼라이즈를 불러올 때 many=True를 사용

(app - models.py )

from django.db import models
from user.models import Users


class Todos(models.Model):
    user = models.ForeignKey(Users, on_delete=models.CASCADE)
    title = models.CharField(max_length=50)
    # 파일 찾기 기능을 고려해 시간대별 저장
    image = models.ImageField(blank=True, upload_to='%Y/%m/%d/')
    is_complete = models.BooleanField(default=False)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    completion_at = models.DateTimeField(auto_now=True)

    def __str__(self):
        return str(self.title)

 

(app - views.py)

from rest_framework.permissions import IsAuthenticated
from rest_framework import status
from rest_framework.response import Response
from rest_framework.views import APIView
from todo.models import Todos      
from todo.serializers import TodoSerialize


class TodoView(APIView):
    # 로그인한 유저인지 확인
    permission_classes = [IsAuthenticated]
    def get(self, request):
        todo = Todos.objects.all()
        # 여러개의 시리얼라이즈를 불러올 때 many=True를 사용
        serialize = TodoSerialize(todo, many=True)
        return Response(serialize.data, status=status.HTTP_200_OK)

 

(app - serializers.py)

from rest_framework import serializers
from todo.models import Todos

class TodoSerialize(serializers.ModelSerializer):
    class Meta:
        model = Todos
        fields = '__all__'

 

 

 

 

 

 

Todo 생성

  • 게시글 작성은 title과 image 데이터만 받음
  • user는 데이터를 실어온 시리얼라이즈에 로그인한 유저의 정보를 추가하여 저장

 

(app - views.py)

from todo.serializers import TodoCreateSerialize

class TodoView(APIView):
    def post(self, request):
        serialize = TodoCreateSerialize(data=request.data)
        if serialize.is_valid():
            # user를 저장하지 않으면 에러남
            serialize.validated_data['user'] = request.user
            serialize.save()
            # 또는 아래와 같이 유저를 저장할 수 있다.
            # serialize.save(user=request.user)
            return Response(serialize.data, status=status.HTTP_201_CREATED)
        else:
            return Response({'message':f'${serialize.errors}'}, status=status.HTTP_400_BAD_REQUEST)

 

(app - serializers.py)

class TodoCreateSerialize(serializers.ModelSerializer):
    class Meta:
        model = Todos
        fields = ['title', 'image']

 

https://www.django-rest-framework.org/api-guide/fields/

 

 

 

 

 

Todo 수정, 삭제하기

  • 개인페이지의 열람, 수정, 삭제는 로그인한 유저와 게시글을 쓴 유저의 정보가 일치할 때만 가능
  • 객체가 존재하지 않으면 404 에러를 발생

 

(app - views.py)

class TodoDetailView(APIView):
    permission_classes = [IsAuthenticated]

    def get(self, request, todo_id):
        # 객체가 존재하지 않으면 404에러를 발생
        todo = get_object_or_404(Todos, id=todo_id)
        if request.user == todo.user:
            serialize = TodoSerialize(todo)
            return Response(serialize.data, status=status.HTTP_200_OK)
        else:
            return Response({'message':'권한이 없습니다.'}, status=status.HTTP_400_BAD_REQUEST)
    
    def put(self, request, todo_id):
        todo = get_object_or_404(Todos, id=todo_id)
        if request.user == todo.user:
            serialize = TodoCreateSerialize(todo, data=request.data)
            if serialize.is_valid():
                serialize.save()
                return Response(serialize.data, status=status.HTTP_200_OK)
            else:
                return Response({'message':'데이터가 옳바르지 않습니다.'}, status=status.HTTP_400_BAD_REQUEST)
        else:
            return Response({'message':'권한이 없습니다.'}, status=status.HTTP_400_BAD_REQUEST)   
    
    def delete(self, request, todo_id):
        todo = get_object_or_404(Todos, id=todo_id)
        if request.user == todo.user:
            todo.delete()
            return Response({'message':'삭제 완료'},status=status.HTTP_204_NO_CONTENT)
        else:
            return Response({'message':'권한이 없습니다.'}, status=status.HTTP_400_BAD_REQUEST)

 

 

 

 

 

 

 

 

+) 시리얼라이즈를 활용( get_user 메소드 )하여 user를 보여줄 때 email로 보여줄 수 있다.

from rest_framework import serializers
from todo.models import Todos


class TodoSerialize(serializers.ModelSerializer):
    user = serializers.SerializerMethodField()

    # user attribute(변수) 앞에 get을 사용
    # obj는 해당 Article
    def get_user(self, obj):
        # return 값이 user라는 attribute 값에 들어감
        return obj.user.email
        
    class Meta:
        model = Todos
        fields = '__all__'

 

스태틱, 미디어 폴더

  • 장고에서 스태틱, 미디어 폴더를 사용하기 위해서는 Pillow를 설치해야 한다.
  • 미디어 폴더의 경우 .gitignore에 등록하면 깃에 업로드 되는 것을 피할 수 있다.
  • runserver(개발환경)에서 media 파일 서빙을 권장하지 않는다.
  • 이 때문에 urlpatterns을 작성하면 파일이 서빙된다.

 

https://docs.djangoproject.com/en/4.2/howto/static-files/

 

 

pip install Pillow

 

 

(settings.py)

STATIC_ROOT = BASE_DIR / 'static'
STATIC_URL = '/static/'

MEDIA_ROOT = BASE_DIR / 'media'
MEDIA_URL = '/media/'

 

 

(urls.py)

from django.conf import settings
from django.conf.urls.static import static

urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

 

 

 

 

 

 이미지 등록하기

  • postman에서 이미지 등록시 form-data를 사용

 

 

 

 

 

 

 

 

 

 

 

 

+) access 토큰을 enviroments에 등록하여 쓸 수 있다.

        *단, 처음 작성할 때와 달리 Current value가 자동으로 변경되지 않으므로, Initial value, Current value  둘 다 입력해야한다.

'Python > Django' 카테고리의 다른 글

[DRF] 11. 댓글 API(두 개의 모델 참조)  (0) 2023.04.26
[DRF] 10. 게시글 API  (0) 2023.04.26
[DRF] 08.5 토큰 주기설정, permission  (0) 2023.04.26
[DRF] 08. Payload 커스텀  (0) 2023.04.26
[DRF] 07. 유저 API  (0) 2023.04.26

토큰 주기 설정 

 

https://django-rest-framework-simplejwt.readthedocs.io/en/latest/settings.html

 

 

(settings.py)

    배포할 때는 access 토큰 평균 5~30분 정도

from datetime import timedelta

SIMPLE_JWT = {
    "ACCESS_TOKEN_LIFETIME": timedelta(minutes=100),
    "REFRESH_TOKEN_LIFETIME": timedelta(days=1),
    "ROTATE_REFRESH_TOKENS": False,
    "BLACKLIST_AFTER_ROTATION": False,
    "UPDATE_LAST_LOGIN": False,

    "ALGORITHM": "HS256",
    "SIGNING_KEY": SECRET_KEY,
    "VERIFYING_KEY": "",
    "AUDIENCE": None,
    "ISSUER": None,
    "JSON_ENCODER": None,
    "JWK_URL": None,
    "LEEWAY": 0,

    "AUTH_HEADER_TYPES": ("Bearer",),
    "AUTH_HEADER_NAME": "HTTP_AUTHORIZATION",
    "USER_ID_FIELD": "id",
    "USER_ID_CLAIM": "user_id",
    "USER_AUTHENTICATION_RULE": "rest_framework_simplejwt.authentication.default_user_authentication_rule",

    "AUTH_TOKEN_CLASSES": ("rest_framework_simplejwt.tokens.AccessToken",),
    "TOKEN_TYPE_CLAIM": "token_type",
    "TOKEN_USER_CLASS": "rest_framework_simplejwt.models.TokenUser",

    "JTI_CLAIM": "jti",

    "SLIDING_TOKEN_REFRESH_EXP_CLAIM": "refresh_exp",
    "SLIDING_TOKEN_LIFETIME": timedelta(minutes=5),
    "SLIDING_TOKEN_REFRESH_LIFETIME": timedelta(days=1),

    "TOKEN_OBTAIN_SERIALIZER": "rest_framework_simplejwt.serializers.TokenObtainPairSerializer",
    "TOKEN_REFRESH_SERIALIZER": "rest_framework_simplejwt.serializers.TokenRefreshSerializer",
    "TOKEN_VERIFY_SERIALIZER": "rest_framework_simplejwt.serializers.TokenVerifySerializer",
    "TOKEN_BLACKLIST_SERIALIZER": "rest_framework_simplejwt.serializers.TokenBlacklistSerializer",
    "SLIDING_TOKEN_OBTAIN_SERIALIZER": "rest_framework_simplejwt.serializers.TokenObtainSlidingSerializer",
    "SLIDING_TOKEN_REFRESH_SERIALIZER": "rest_framework_simplejwt.serializers.TokenRefreshSlidingSerializer",
}

 

 

 

 

permission

 

(app-views.py)

from rest_framework import permissions

class MockView(APIView):
    #로그인 확인
    permission_classes = [permissions.IsAuthenticated]
    def get(self, request):
        return Response('get 요청')

 

refresh 토큰으로 access 토큰 받기

    Body에 refresh 토큰을 입력하면 access 토큰을 받을 수 있다.

 

'Python > Django' 카테고리의 다른 글

[DRF] 10. 게시글 API  (0) 2023.04.26
[DRF] 09. 스태틱, 미디어 폴더 세팅  (0) 2023.04.26
[DRF] 08. Payload 커스텀  (0) 2023.04.26
[DRF] 07. 유저 API  (0) 2023.04.26
[DRF] 06.5 admin 커스텀  (0) 2023.04.25

Payload 커스텀

  • JWT Payload에 모델에서 작성한 필드를 추가하기

 

https://django-rest-framework-simplejwt.readthedocs.io/en/latest/customizing_token_claims.html

 

(app-views.py)

from users.serializers import CustomTokenObtainPairSerializer
from rest_framework_simplejwt.views import TokenObtainPairView

class CustomTokenObtainPairView(TokenObtainPairView):
    serializer_class = CustomTokenObtainPairSerializer

 

 

(app-serializers.py)

class CustomTokenObtainPairSerializer(TokenObtainPairSerializer):
    @classmethod
    def get_token(cls, user):
        token = super().get_token(user)
        token['email'] = user.email
        token['bio'] = user.bio
        token['name'] = user.name
        token['age'] = user.age
        token['gender'] = user.gender

        return token

 

 

(app-urls.py) 수정하기

urlpatterns = [
    path('api/token/', views.CustomTokenObtainPairView.as_view(), name='token_obtain_pair'),
]

 

'Python > Django' 카테고리의 다른 글

[DRF] 09. 스태틱, 미디어 폴더 세팅  (0) 2023.04.26
[DRF] 08.5 토큰 주기설정, permission  (0) 2023.04.26
[DRF] 07. 유저 API  (0) 2023.04.26
[DRF] 06.5 admin 커스텀  (0) 2023.04.25
[DRF] 06. User / UserManager  (0) 2023.04.24

회원가입

  • 시리얼라이즈 fields로 Users 모델의 필드를 전부 가져온다.
  • 시리얼라이즈 생성시 비밀번호가 노출되지 않도록 해싱한다.

 

(app-urls.py)

from users import views

urlpatterns = [
    path('signup/', views.UserView.as_view(), name='user_view'),
    ]

 

(app-views.py)

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from users.serializers import UserSerializer


class UserView(APIView):
    def post(self, request):
        serialize = UserSerializer(data=request.data)
        if serialize.is_valid():
            serialize.save()
            return Response({'message':'가입완료'}, status=status.HTTP_201_CREATED)
        else:
            return Response({'message':f'${serialize.errors}'}, status=status.HTTP_400_BAD_REQUEST)

 

(app-serializers.py)

from rest_framework import serializers
from user.models import Users


class UserSerialize (serializers.ModelSerializer):
    class Meta:
        model = Users
        fields = '__all__'

    def create(self, validated_data):
        user = super().create(validated_data)
        password = user.password
        user.set_password(password)
        user.save()
        return user

 

 

 

 

회원 수정, 삭제

  • 특정 회원 정보가 필요하므로 url을 통해 유저의 id를 전송한다.
  • 로그인한 유저와 전송된 유저의 id가 동일할 때 수정, 삭제한다.
  • 이메일 수정 요청을 해도 로그인한 유저의 이메일로 되돌려보낸다. (이메일 고정)
  • 업데이트 할 때도 비번을 해싱하여 저장한다.

(app - urls.py)

urlpatterns = [
    path('<int:user_id>/', views.UserDetailView.as_view(), name='user_detail_view'),
]

 

(app - views.py)

from user.models import Users


class UserDetailView(APIView):
    def delete(self, request, user_id):
        compare_user = get_object_or_404(Users, id=user_id)
        if request.user == compare_user:
            compare_user.delete()
            return Response('회원 탈퇴.', status=status.HTTP_204_NO_CONTENT)
        else:
            return Response('삭제 못함', status=status.HTTP_403_FORBIDDEN)
        
    def put(self, request, user_id):
        compare_user = get_object_or_404(Users, id=user_id)
        if request.user == compare_user:
            serialize = UserSerialize(compare_user, data=request.data)
            if serialize.is_valid():
                serialize.email=request.user.email,
                serialize.save()
            return Response('회원 수정', status=status.HTTP_200_OK)
        else:
            return Response('수정 못함', status=status.HTTP_403_FORBIDDEN)

 

(app - serializers.py)

# 추가하기
class UserSerialize (serializers.ModelSerializer):
    # 이메일을 아이디 값으로 취급
    # 비번은 해싱
    def update(self, instance, validated_data):
        password = validated_data.get('password', instance.password)
        instance.set_password(password)
        instance.bio = validated_data.get('bio', instance.bio)
        instance.name = validated_data.get('name', instance.name)
        instance.age = validated_data.get('age', instance.age)
        instance.gender = validated_data.get('gender', instance.gender)
        instance.save()
        return instance

 

'Python > Django' 카테고리의 다른 글

[DRF] 08.5 토큰 주기설정, permission  (0) 2023.04.26
[DRF] 08. Payload 커스텀  (0) 2023.04.26
[DRF] 06.5 admin 커스텀  (0) 2023.04.25
[DRF] 06. User / UserManager  (0) 2023.04.24
[DRF] 05. 기본 JWT 토큰  (0) 2023.04.24

admin 커스텀

    사용자 추가, 변경에 사용할 폼을 별도로 만들어 설정해 줄 수도 있다.

 

 

(app-admin.py)

 

from django import forms
from django.contrib import admin
from django.contrib.auth.models import Group
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from django.contrib.auth.forms import ReadOnlyPasswordHashField
from django.core.exceptions import ValidationError

from user.models import Users

# admin 페이지
class UserAdmin(BaseUserAdmin):
    # 아래처럼 사용자 추가, 변경에 사용할 폼을 지정 가능
    # form = UserChangeForm
    # add_form = UserCreationForm

    # admin 리스트에 표시될 필드
    list_display = ["id","email", "is_admin"]
    list_filter = ["is_admin"]
    # admin의 user수정 페이지에서 보여지는 부분
    fieldsets = [
        (None, {"fields": ["password", "gender", "age", "bio"]}),
        ("Permissions", {"fields": ["is_admin"]}),
    ]

    # admin의 user생성 페이지에서 보여지는 부분
    add_fieldsets = [
        (
            None,
            {
                "classes": ["wide"],
                "fields": ["email", "password1", "password2", "name", "gender", "age", "bio"],
            },
        ),
    ]
    # 검색 필드
    search_fields = ["email"]
    ordering = []
    filter_horizontal = []

admin.site.register(Users, UserAdmin)
# Group 모델을 등록 해제(사용x)
admin.site.unregister(Group)

 

 

 

 

JWT 커스텀 공식문서

https://docs.djangoproject.com/en/4.2/topics/auth/customizing/

'Python > Django' 카테고리의 다른 글

[DRF] 08. Payload 커스텀  (0) 2023.04.26
[DRF] 07. 유저 API  (0) 2023.04.26
[DRF] 06. User / UserManager  (0) 2023.04.24
[DRF] 05. 기본 JWT 토큰  (0) 2023.04.24
[DRF] 04.5 Fetch API, CORS 에러  (0) 2023.04.24

User / UserManager

 

  • manager 클래스를 통해 DB와 데이터를 주고 받는다.
  • User와 함께 BaseUserManger를 만들어 주어야 한다.
  • 장고가 만들어준 필수사항이 존재한다.

 

(settings.py)

#users 앱의 User 모델
AUTH_USER_MODEL = "user.Users"

 

 

(app - models.py)

from django.db import models
from django.contrib.auth.models import BaseUserManager, AbstractBaseUser


# User를 생성할 때 사용하는 헬퍼 클래스
class UserManager(BaseUserManager):
    # 사용자를 생성
    def create_user(self, email, name, gender,  age, bio, password=None):
        if not email:
            raise ValueError("이메일을 입력하세요")
        user = self.model(
            email=self.normalize_email(email),
            name=name,
            gender=gender,
            age=age,
            bio=bio,
        )
        # 장고에서 제공하는 password 설정 함수
        user.set_password(password)
        user.save(using=self._db)
        return user

    # 관리자 생성
    def create_superuser(self, email, name, gender, age, bio, password=None):
        user = self.create_user(
            email,
            name=name,
            gender=gender,
            age=age,
            bio=bio,
            password=password,
        )
        user.is_admin = True
        user.save(using=self._db)
        return user


class Users(AbstractBaseUser):
    GENDER_CHOICE = {
        ('male', 'Male'),
        ('female', 'Female'),
    }

    email = models.EmailField(max_length=255, unique=True)
    name = models.CharField(max_length=30)
    gender = models.CharField(max_length=10, choices=GENDER_CHOICE, blank=True)
    age = models.PositiveIntegerField(default=0, blank=True)
    bio = models.TextField(blank=True)

    # User 모델의 필수 field
    is_active = models.BooleanField(default=True)
    is_admin = models.BooleanField(default=False)

    # 헬퍼 클래스 사용
    objects = UserManager()

    # 쉽게 말해 login ID
    USERNAME_FIELD = "email"

    # 이거 없으면 cratesuperuser 만들때 에러남
    REQUIRED_FIELDS = ["name", "gender", "age", "bio"]

    def __str__(self):
        return self.email
    
    def has_perm(self, perm, obj=None):
        "Does the user have a specific permission?"
        return True

    def has_module_perms(self, app_label):
        "Does the user have permissions to view the app `app_label`?"
        return True

    @property
    def is_staff(self):
        "Is the user a member of staff?"
        return self.is_admin

 

 

'Python > Django' 카테고리의 다른 글

[DRF] 07. 유저 API  (0) 2023.04.26
[DRF] 06.5 admin 커스텀  (0) 2023.04.25
[DRF] 05. 기본 JWT 토큰  (0) 2023.04.24
[DRF] 04.5 Fetch API, CORS 에러  (0) 2023.04.24
[DRF] 04. 클래스 뷰(CBV)  (0) 2023.04.24

JWT 토큰 기본 설정

JWT 공식문서

https://django-rest-framework-simplejwt.readthedocs.io/en/latest/

 

 

+) 토큰 정리

https://winterakoon.tistory.com/145

 

pip install djangorestframework-simplejwt

#users 앱 만들고 settings, urls 세팅
python manage.py startapp users

 

(settings.py)

#추가하기
INSTALLED_APPS = [
    'rest_framework_simplejwt',
]


REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework_simplejwt.authentication.JWTAuthentication',
    )
}

 

 

(app - urls.py)

from rest_framework_simplejwt.views import (
    TokenObtainPairView,
    TokenRefreshView,
)


#추가하기
urlpatterns = [
    path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
    path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
]

 

 

 

 

 

 

 

 

 

 

Token으로 로그인

python manage.py createsuperuser

 

 

 

 

 

 

 

토큰 만료 기간 설정

  • access 토큰은 사용하면 만료됨
  • JWT의 경우 보안상의 이유로 refresh 토큰을 이용
  • 만료 기간을 조정할 수 있다.
SIMPLE_JWT = {
    "ACCESS_TOKEN_LIFETIME": timedelta(minutes=5),
    "REFRESH_TOKEN_LIFETIME": timedelta(days=1),
    }

 

'Python > Django' 카테고리의 다른 글

[DRF] 06.5 admin 커스텀  (0) 2023.04.25
[DRF] 06. User / UserManager  (0) 2023.04.24
[DRF] 04.5 Fetch API, CORS 에러  (0) 2023.04.24
[DRF] 04. 클래스 뷰(CBV)  (0) 2023.04.24
[DRF] 03. postman-1, swagger  (0) 2023.04.24

Fetch API 사용

  • javascript에서 접근하고 조작할 수 있는 인터페이스를 제공
  • 네트워크의 리소스를 쉽게 비동기적으로 가져올 수도 있다.

 

(index.html)

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>프론트엔드</title>
</head>
<script src="index..js">
</script>

<body>
    <h1>프론트엔드인가</h1>
    이렇게 제출하면 욕먹지 않나? 아니면 말고
    <div id="articles"></div>
</body>

</html>

 

 

 

동기 / 비동기 처리

    동기

        순차적으로 처리. 요청과 응답의 순서를 보장받음

    비동기

        병렬적으로 처리. 자원을 효율적으로 사용(처리 시간이 빠름)

 

 

async / await

  • 내부적으로 promise 방식으로 비동기 처리
  • 함수 앞에 async 를 붙이고 비동기로 처리할 부분 앞에 await를 붙임
  • 문법 형태만 간결해짐

 

(index.js)

//로딩이 될 때
window.onload = async function loadArticles() {
    //fetch안의 주소를 get방식으로 보냄
    //fetch 함수는 promise 객체를 반환
    //await를 사용하여 Promise 객체가 반환 될 때까지 기다림
    const response = await fetch('http://127.0.0.1:8000/articles/', { method: 'GET' })
	//response.json()을 호출하여 JSON 형태의 데이터를 파싱하여 반환
    response_json = await response.json()

    console.log(response_json)

    const articles = document.getElementById('articles')

    response_json.forEach(element => {
        console.log(element.title)
        const newArticle = document.createElement('div')
        newArticle.innerText = element.title
        articles.appendChild(newArticle)
    })
}

 

 

 

 

 

CORS 에러 

    (보안) 주소와 포트가 다를 때 발생, 별도의 허용이 필요함

 

pip install django-cors-headers

 

(settings.py)

INSTALLED_APPS =[
'corsheaders', 
]


MIDDLEWARE = [
	'corsheaders.middleware.CorsMiddleware',
    #'django.middleware.common.CommonMiddleware', # 얘 위에 추가
]


#보안에 안 좋음
CORS_ALLOW_ALL_ORIGINS = True

 

'Python > Django' 카테고리의 다른 글

[DRF] 06. User / UserManager  (0) 2023.04.24
[DRF] 05. 기본 JWT 토큰  (0) 2023.04.24
[DRF] 04. 클래스 뷰(CBV)  (0) 2023.04.24
[DRF] 03. postman-1, swagger  (0) 2023.04.24
[DRF] 02. @api_view  (0) 2023.04.24

+ Recent posts