Django投稿&いいですね&follow
Westagramプロジェクトを行い、初期設定からログイン機能まで実現しました.ここでは、追加のタスク投稿、コメント、良いfollow機能を実現することで、Django APIの作成をより熟知しています.
Djangoでは、主に処理するデータの種類が異なる場合にアプリケーションを分離することが望ましい.したがって、postingsというアプリケーションが新しく作成され、新しいテーブル間でモデリングされ、ERDが作成されます.
ERDは以下を含む.
モデリングのERDに基づいてモデルを作成した.
ERDでは、2つのForeignKeyが1つのクラスで同じオブジェクトを参照し、関連するnameを使用しない場合、次のエラーが発生します.
Followクラスではfollow、follow Fieldが同じUserクラスオブジェクトを参照するため、この2つのインスタンスを指定しないと区別できません.
したがって、Userクラスオブジェクトを参照するフィールドはrelated nameで区切らなければなりません.
すでに点賛と注目を集めている場合、同じ要求を出すと、点賛が解除され、注目されないことが実現します.
従来の基数がget or createメソッドで実現されているのを見ると,確かにコードが簡潔になるにつれてcreate,delete機能を同時に処理できるのは良い方法である.
Model
Djangoでは、主に処理するデータの種類が異なる場合にアプリケーションを分離することが望ましい.したがって、postingsというアプリケーションが新しく作成され、新しいテーブル間でモデリングされ、ERDが作成されます.
ERDは以下を含む.
モデリングのERDに基づいてモデルを作成した.
# posings/models.py
from django.db import models
class Posting(models.Model):
image_url = models.URLField()
content = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
user = models.ForeignKey('users.User', on_delete=models.CASCADE)
class Meta:
db_table = 'postings'
class Comment(models.Model):
user = models.ForeignKey('users.User', on_delete=models.CASCADE)
posting = models.ForeignKey('Posting', on_delete=models.CASCADE)
content = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
class Meta:
db_table = 'comments'
class Like(models.Model):
user = models.ForeignKey('users.User', on_delete=models.CASCADE)
posting = models.ForeignKey('Posting', on_delete=models.CASCADE)
class Meta:
db_table = 'likes'
Postings appがユーザー・アプリケーションのユーザー・カテゴリとしてForeignKeyを使用している場合、参照するテーブルの名前はAppNameです.正しく適用するには、Table Nameとして指定します.# users/models.py
from django.db import models
class User(models.Model):
name = models.CharField(max_length=30)
email = models.EmailField(max_length=50, unique=True)
password = models.CharField(max_length=120)
phone_number = models.CharField(max_length=20)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
db_table = 'users'
class Follow(models.Model):
follow = models.ForeignKey('User', on_delete=models.CASCADE, related_name='follow')
followed = models.ForeignKey('User', on_delete=models.CASCADE, related_name='followed')
class Meta:
db_table = 'follows'
followとfollowはユーザ間で発生する機能であるためusers appで作成される.ERDでは、2つのForeignKeyが1つのクラスで同じオブジェクトを参照し、関連するnameを使用しない場合、次のエラーが発生します.
Followクラスではfollow、follow Fieldが同じUserクラスオブジェクトを参照するため、この2つのインスタンスを指定しないと区別できません.
したがって、Userクラスオブジェクトを参照するフィールドはrelated nameで区切らなければなりません.
Posting View
class PostingView(View):
def post(self, request):
try:
data = json.loads(request.body)
image_url = data['image_url']
content = data['content']
user = User.objects.get(email=data['email'])
if not User.objects.filter(email=data['email']).exists():
return JsonResponse({'message':'INVALID_USER'}, status=401)
Posting.objects.create(
image_url = image_url,
content = content,
user = user
)
return JsonResponse({'message':'SUCCESS'}, status=201)
except KeyError:
return JsonResponse({'message':'KEY_ERROR'}, status=400)
def get(self, request, posting_id):
if not Posting.objects.filter(id=posting_id).exists():
return JsonResponse({'message':'NON_POST'}, status=400)
posting = Posting.objects.get(id=posting_id)
results = []
results.append(
{
'user' : posting.user.email,
'image_url' : posting.image_url,
'content' : posting.content,
'created_at' : posting.created_at
}
)
return JsonResponse({'results':results}, status=200)
# postings/urls.py
urlpatterns = [
path('/posting', PostingView.as_view()),
path('/posting/<int:posting_id>', PostingView.as_view()),
]
特定の投稿の情報のみを取得するためにurls.pyには整数型idを参照するコードが追加されています.また,GETメソッドにpost idパラメータを追加する.これでpost/1はID 1の投稿をロードできます.http -v POST 127.0.0.1:8000/postings/posting email='r123@gma
il.com' image_url='https://cdn.pixabay.com/photo/2022/01/29/11/02/cat-6977096_1280.jpg' content='고양이 사진'
http -v GET 127.0.0.1:8000/postings/posting/2
Comment View
class CommentView(View):
def post(self, request):
try:
data = json.loads(request.body)
content = data['content']
user = User.objects.get(email=data['email'])
if not User.objects.filter(email=data['email']).exists():
return JsonResponse({'message':'INVALID_USER'}, status=401)
if not Posting.objects.filter(id=data['posting_id']).exists():
return JsonResponse({'message':'NON_POST'}, status=401)
Comment.objects.create(
user = user,
posting_id = data['posting_id'],
content = content
)
return JsonResponse({'message':'SUCCESS'}, status=201)
except KeyError:
return JsonResponse({'message':'KEY_ERROR'}, status=400)
def get(self, request, posting_id):
comments = Comment.objects.filter(posting_id=posting_id)
results = [{
'user' : comment.user.email,
'content' : comment.content,
'created_at' : comment.created_at
} for comment in comments]
return JsonResponse({'reuslts':results}, status=200)
urlpatterns = [
path('/posting', PostingView.as_view()),
path('/posting/<int:posting_id>', PostingView.as_view()),
path('/comment', CommentView.as_view()),
path('/<int:posting_id>/comment', CommentView.as_view()),
]
PostingViewのように特定の投稿に関するコメント、URLのみを取得するために.pyに整数型idを参照するコードを追加し、パラメータも追加しました. http -v POST 127.0.0.1:8000/postings/comment email='[email protected]' content='귀여운 고양이네요' posting_id=2
http -v GET 127.0.0.1:8000/postings/2/comment
Like View & Follow View
class LikeView(View):
def post(self, request):
try:
data = json.loads(request.body)
user = User.objects.get(email=data['email'])
if not User.objects.filter(email=data['email']).exists():
return JsonResponse({'message':'INVALID_USER'}, status=401)
if not Posting.objects.filter(id=data['posting_id']).exists():
return JsonResponse({'message':'NON_POST'}, status=401)
like = Like.objects.filter(user=user, posting_id=data['posting_id'])
if like.exists():
like.delete()
return JsonResponse({'message':'LIKE_DELETE'}, status=200)
Like.objects.create(
user = user,
posting_id = data['posting_id']
)
# like, is_like = Like.objects.get_or_create(
# user = user,
# posting_id = data['posting_id']
# )
# if not is_like:
# like.delete()
# return JsonResponse({"message":"LIKE_DELETE"}, status=200)
return JsonResponse({'message':'SUCCESS'}, status=201)
except KeyError:
return JsonResponse({'message':'KEY_ERROR'}, status=400)
class FollowView(View):
def post(self, request):
try:
data = json.loads(request.body)
follow_id = data['follow_id']
followed_id = data['followed_id']
if not User.objects.filter(id=follow_id).exists():
return JsonResponse({'message':'INVALID_USER'}, status=401)
if not User.objects.filter(id=followed_id).exists():
return JsonResponse({'message':'INVALID_USER'}, status=401)
follow = Follow.objects.filter(follow_id=follow_id, followed_id=followed_id)
if follow.exists():
follow.delete()
return JsonResponse({'message':'UNFOLLOWED'}, status=200)
Follow.objects.create(
follow_id = follow_id,
followed_id = followed_id
)
# follow, is_follow = Follow.objects.get_or_create(
# follow = User.objects.get(email=data['follow']),
# followed = User.objects.get(email=data['followed'])
# )
# if not is_follow:
# follow.delete()
# return JsonResponse({"MESSAGE":"UNFOLLOWED"}, status=200)
return JsonResponse({'message':'FOLLOWED'}, status=201)
except KeyError:
return JsonResponse({'message':'KEY_ERROR'}, status=400)
http -v POST 127.0.0.1:8000/postings/like email='[email protected]' posting_id=2
http -v POST 127.0.0.1:8000/postings/follow follow_id=5 followed_id=4
すでに点賛と注目を集めている場合、同じ要求を出すと、点賛が解除され、注目されないことが実現します.
従来の基数がget or createメソッドで実現されているのを見ると,確かにコードが簡潔になるにつれてcreate,delete機能を同時に処理できるのは良い方法である.
Reference
この問題について(Django投稿&いいですね&follow), 我々は、より多くの情報をここで見つけました https://velog.io/@cghy4862/Django-게시물-댓글-좋아요-followテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol