๐ DRF ๊ตฌ์ฑํ๊ธฐ
์๋ฒ ๋ง๋ค ๋ DRF ๋ ์ ๋ง ํธ๋ฆฌํ๋ค. ๋ง๊ทธ๋๋ก ๋-๋ฑ ๋ง๋ค ์ ์๋ค. ์ฐ์ ๋ชจ๋ธ์ ๋ง๋ค์ด๋ณด์.
class Item(models.Model):
id = models.IntegerField(primary_key=True)
category = models.CharField(max_length=30)
title = models.CharField(max_length=30)
stack = models.CharField(max_length=200)
markdown_content = models.TextField()
created_date = models.DateTimeField(default=timezone.now)
def set_stack(self, x):
self.stack = json.dumps(x)
def get_stack(self):
return json.loads(self.stack)
def __str__(self):
return self.title
class Meta:
db_table = "item"
from rest_framework import serializers
class ItemSerializer(serializers.ModelSerializer):
class Meta:
model = Item
fields = ('id','category','title','stack','markdown_content','created_date')
ํ๋์ ํ์ผ์ ๋ชจ๋ธ๊ณผ Serializer๋ฅผ ์ ์ํ๋ค. Serializer๋ ๋ชจ๋ธ object๋ฅผ front์์ ๊บผ๋ด์ฐ๊ธฐ ์ฝ๊ฒ ๊ฐ๊ณตํด์ฃผ๋ ๋์ด๋ค. Item class์ set_stack, get_stack ์ List ํํ์ Column์ ๊ฐ๊ณตํด์ฃผ๊ธฐ์ํด ์ผ๋ค. SQL์์ List๋ฅผ ๊ฐ๊ณตํด์ฐ๋ ๊ฒ์ ์ฐ์ํ์ง๋ ์์ง๋ง ๋ง๊ทธ๋๋ก ํ ์ด ํ๋ก์ ํธ๋๊น.
์ด์ View๋ฅผ ๋ง๋ค์ด ๋ณด์
class ItemViewSet(APIView):
def get(request,**kwargs):
qs = Item.objects.all()
sc = ItemSerializer
category = kwargs.get('category')
qs = qs.filter(category=category)
sc = sc(qs,many=True)
sc = (json.dumps(sc.data))
return HttpResponse(sc)
์นดํ
๊ณ ๋ฆฌ ๋ณ๋ก data๋ฅผ ๊ฐ์ ธ์ค๋ ๋ถ๋ถ์ด๋ค. react์์ ์์ฒญํ ์นดํ
๊ณ ๋ฆฌ๋ฅผ **kwargs๋ก ๋ฐ๋๋ค. **kwargs ๋ ์์ฒญํ ๊ฐ์ dict๋ก ๋ฐ์์ฃผ๋ ๋์ธ๋ฐ ๋ณดํต ์์ธก '๋ถ'๊ฐ๋ฅํ ๊ฐ์ด ์ฌ ๋ ์จ์ฃผ๋ฉด ์ ์ฐํ๊ฒ ์๋ํ๋ค. all() ๋ถ๋ถ์์ ๋ฐ๋ก filter๋ก ํ ์ค๋ก ์์ฑํ๋ ๊ฒ๋ ๋ฌผ๋ก ๊ฐ๋ฅํ์ง๋ง ์ ์ ๊ธฐ๋ฅ์ด ์ถ๊ฐ๋๋ค ๋ณด๋ ์ผ๋จ ์์ ์ ๋ฏธ๋ฃจ๊ณ ์๋ค. Serializer ๊ฐ์ฒด๋ฅผ ๋ง๋ค๊ณ json.dumps๋ก json ํํ๋ก ๊ฐ๊ณต ํ ๋ฐ๋ก Json์ react์๊ฒ ๋ณด๋ด์ค๋ค.
path('item/<str:category>/',ItemViewSet.get)
react์์๋ ์๊ธฐ path์ ๊ฐ์ด example.com/item/categoryA/ ๋ก ๋ฐ์ดํฐ๋ฅผ ์์ฒญํ๊ณ json์ ๋ฆฌํด๋ฐ๋๋ค. ์ฐธ๊ณ ๋ก ์์ชฝ ๋ค ๋งจ ๋์ / ๋ฅผ ๋ถ์ฌ์ผ ํจ์ ์ฃผ์ํ์. ํฌํธํด๋ฆฌ์ค์ Admin์ ๋ง๋ค์ด์ ์๋ก์ด ์นดํ
๊ณ ๋ฆฌ๋ฅผ ๋ฃ์ผ๋ฉด ์นดํ
๊ณ ๋ฆฌ ํญ์ด ์๋์ผ๋ก ์ถ๊ฐ๋์ด ์ ํํ ์ ์๋๋ก ๋ง๋ค ์์ ์ด๋ค. Velog์ ํ๊ทธ ์ฒ๋ผ.
๐คข๐คข๐คข
API ์๋ฒ๋ฅผ ๋ถ์ฌ heroku์ ๋ฐฐํฌํ์ฌ url๋ก ์ ๊ทผ์ ํด๋ณด๋ ์ฅ๊ณ ๊ฐ ๋์จ๋ค. ์ฆ API ์๋ฒ๊ฐ ํด๋ผ์ด์ธํธ ์ฌ์ด๋์ ๋
ธ์ถ์ด ๋๋ ๊ฒ์ด๋ค. ๋
ธ์ถ์ด ๋๋ ๊ฒ์ด ๋ฌธ์ ๊ฐ ์๋๋ผ heroku์์ react์ router๋ณด๋ค django์ url์ ์ฐ์ ์ผ๋ก ๋์ด react๊ฐ ๋ณด์ด์ง ์๋๋ค. react๊ฐ ๋์๋ refresh๋ฅผ ํ๋ฉด ๋ค์ api ์๋ฒ(์ฅ๊ณ ) ๊ฐ ๋์จ๋ค.
๋ค์ ์๊ฐํด๋ณด์. ๊ฐ๋ฐ ํ๊ฒฝ์์๋ react ๋ฅผ 5000๋ฒ ํฌํธ, django ๋ฅผ 8000๋ฒ ํฌํธ๋ก ์ฌ์ฉํ๊ณ ์ด๋ค๊ณผ์ ํต์ ์ axios ๋ก ํฌํธ ๋ฒํธ๋ฅผ ์ง์ ํด์ ํ๋ค.
return await axios
.get('http://127.0.0.1:8000/project/');
}
heroku๋ ์ด๋จ๊น. ec2์ ๊ฐ์ laas์ ๋ฐฐํฌ๋ฅผ ํ๋ค๊ณ ํ๋ฉด apache ์ค์ ์ ๊ฐ๊ธฐ ๋ค๋ฅธ ํฌํธ๋ก ์ค์ ํ์ฌ ์ด๋ค๊ณผ์ ์ถฉ๋์ ๋ง์ ์ ์๋ค. (์ถฉ๋์ ๋ง๋๋ค๋๊ฒ ์ด์ํ ํํ์ด๊ธด ํ๋ค. ์ ์ด์ ์๋ฒ&ํด๋ผ์ด์ธํธ url, port ์ถฉ๋ ๋ฐ์์ ๊ฐ๋
์ ์์ง๋ ์๋ค.) ํ์ง๋ง heroku์ ๋จ์ผ app์ผ๋ก ์ฅ๊ณ ,๋ฆฌ์กํธ ์กฐํฉ์ ๋ฐฐํฌํ๋ค ๋ณด๋ ์์๊ณผ๋ ๋ค๋ฅด๊ฒ ๋์ํ๋ค. ํฌํธ๋ฅผ ๋ฐ๋ก ์ค์ ํ ๋ฐฉ๋ฒ๋ ์๋ค. ๊ทธ๋์ ํ๋ก ํธ์์ ์ฌ์ฉํ๋ url์ด ์ฅ๊ณ ๋ก ๋ค์ด์์๋ ํ๋ก ํธ๋ก ๋ณด๋ด์ค ํ์๊ฐ ์๋ค.
react_views_regex = r'\/|\b'.join([
'Select',
'skills',
'projects',
'experience'
]) + r'\/'
urlpatterns = [
path('item/<str:category>/',ItemViewSet.get),
re_path('admin/', admin.site.urls),
re_path(react_views_regex,index),
re_path(r'^media/(?P<path>.*)$', serve, {
"document_root": settings.MEDIA_ROOT
}),
re_path(r'^static/(?P<path>.*)$', serve,
{'document_root': settings.STATIC_ROOT}),
]
react_views_regex ์ ํ๋ก ํธ์์ ์ฌ์ฉํ๋ url์ ๋ฑ๋กํด ๋์๋ค. ๋ชจ๋ url์ ๋งตํํ ํ์๋ ์๊ณ ํ๋ก ํธ url ํจํด์์ ๊ณตํต๋๋ ๋ฃจํธ ๋ถ๋ถ๋ง ๊ฐ์ ธ์ค๋ฉด ๋๋ค. ๋ฃจํธ์ธ '/' ๋ฅผ ์ค์ ํด๋ฒ๋ฆฌ๋ฉด ์ฅ๊ณ ์ด๋๋ฏผ, API ์๋ฒ url ๊น์ง ํ๋ก ํธ๋ก ๊ฐ๋ฒ๋ฆฌ๊ธฐ ๋๋ฌธ์ ํ๋ก ํธ์ ์ฌ์ฉ๋๋ ๊ณตํต url ๋ถ๋ถ์ด ์์ผ๋ฉด ์ข๋ค. ์ ๋ฐ์์ผ๋ก urls.py์ ๋ฑ๋กํด์ฃผ๋ฉด ์๊น์ ๊ฐ์ ์ถฉ๋์ ์ผ์ด๋์ง ์๋๋ค.
https://whoami-moonseok.herokuapp.com/