어제 til을 깜빡 했다 .. 그것도 그렇고 머리가 너무 아팠다
단기간에 너무 많은 것을 배울려하니 머리도 더이상 안돌아가고 컨디션도 급격히 나빠진 느낌이라 어제밤에는 거의 기절하듯이 잠을 잔 것 같다..
serialzier 가 보기에는 편해보이지만, 제대로 사용하려면 개념과 원리를 정확하게 알아야한다. django는 조금이라도 어긋나면 바로 오류를 뱉기 때문에, 정확한 데이터를 주고 받아야 한다.
우선 model 설정 부터 잘 연결을 해줘야 하고 serializer를 사용할때 모델을 보면서 관계를 정확하게 파악하고 코딩을 해줘야한다! 안그럼 정말 밑도끝도없이 꼬인다
https://github.com/haajinkim/django_rpac
오늘 저녁에 개인적으로 복습겸 작업을 조금 진행 했었다. 오늘은 전체적인 정리와 복습이 필요 한 것 같다.
class Blog(models.Model):
user = models.ForeignKey(User,on_delete=models.CASCADE)
category = models.ForeignKey('Category',on_delete=models.CASCADE)
title = models.CharField(max_length=50)
desc = models.TextField()
create_date = models.DateTimeField(auto_now=True)
edit_date = models.DateTimeField(auto_now=True)
exposure_end = models.DateTimeField(auto_now_add=False)
class Category(models.Model):
category = models.CharField(max_length=50)
class Comment(models.Model):
user = models.ForeignKey(User,on_delete=models.CASCADE)
title = models.ForeignKey(Blog,on_delete=models.CASCADE)
create_date = models.DateTimeField(auto_now=True)
desc = models.CharField(max_length=50)
우선 Blog , Category ,Comment 라는 모델을 만들었다.
모델간의 관계를 보자면 blgo 가 category 를 정참조 하고 comment가 Categrory 를 정참조한다
class CategorySerializer(serializers.ModelSerializer):
class Meta:
model =Category
fields = ["category"]
class CommentSerializer(serializers.ModelSerializer):
class Meta:
model = Category
fields =["title","create_date","desc"]
class BlogSerializer(serializers.ModelSerializer):
category =CategorySerializer()
comment =serializers.SerializerMethodField()
user = serializers.SerializerMethodField()
def get_comment(self,obj):
comment_list =[{"comment_desc":comment.desc} for comment in obj.comment_set.all()]
print(comment_list)
return comment_list
def get_user(self,obj):
return obj.user.username
class Meta:
model = Blog
fields = ["user","category","comment","title","desc","create_date","edit_date",
"edit_date","exposure_end"]
blog 에서 category, comment 를 전부 가져오려면 생각을 좀 해야한다. 우선 blog 에서 category 는 연결 해주면 바로 가져 올 수 있다. blog model 안에 category 가 존재하기 때문이다. 하지만 여기서 comment 를 가져오려면? 에러가 발생한다.
blog 모델에는 comment 가 없기때문이다. 그래서 comment 를 serializerMethofiedl()필드로 만들어 주고
함수의 obj 를 이용해서 가져올 수 있다. dir(obj)을 해보면 comment_set 이 나온다 (역참조) , relate_name 없이도 바로 역참조 조회가 가능하다. 리스트 컴프리헨션을 이용해서 json 형태로 만들어준뒤 리턴시켜서 넣어주면 조회가 가능하다!
이개념이 시리얼라이즈에서 굉장히 어려웠고 지금도 많이 헷갈리는 개념이다. 개속 반복하면서 연습하는 방법 밖에 없는 것 같다!
다른 모델로 예를 들자면
# 1. obj 을 통해 TagModel object 를 가져온다.
# 2. obj.postmodel_set.all()으로 역참조를 해서 postmodel의 객체를 쿼리셋으로 모두 가져 온다.
# (post -> tag 정참조) (tag -> post) 역참조 tag에는 tag_names 라는 필드밖에 없으니.
# 3. 원하는 데이터만 출력하기위해 리스트 컴프리헨션 을 이용해서 최종출력값 =>
# "author":postmodel.author.username, "content":postmodel.contetns 라는 값만 가져온다
# postmodel => (쿼리셋=obj.postmodel_set.all()).content
# postmodel => (쿼리셋=obj.postmodel_set.all()).author.username
# author.username 은 postmodel에 .author를 조회하면 Usermodel과의 포링키 이기 때문에
# .username 을 통해서 조회한다(정참조.)
class Loginview(APIView):
def post(self, request):
user = authenticate(request, **request.data)
if user:
login(request, user)
return Response({"messge":"로그인 성공!"},status=status.HTTP_200_OK)
return Response({"messge":"존재하지않는 사용자거나 비밀번호가 틀립니다!"},status=status.HTTP_400_BAD_REQUEST)
def delete(self, request):
logout(request)
pass
class Userview(APIView):
def get(self, request):
pass
def post(self, request):
user_serializer = UserSerializer(data=request.data)
user_serializer.is_valid(raise_exception=True)
user_serializer.save()
return Response(user_serializer.data,status=status.HTTP_200_OK)
로그인 로그아웃은 간단하게 구현이 가능하다. 비밀번호는 원래는 평면화 되서 들어가는데 그러면 로그인을 할 수가 없다.
해슁 되있는 비밀번호로 로그인을 해야 하기에
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ["username","email","password","fullname"]
extra_kwargs = {
"password" : {"write_only": True}
}
def create(self, validated_data):
password = validated_data.pop("password","")
#받아온 데이터에서 password 만빼내서 따로저장
user =User(**validated_data)
user.set_password(password)
user.save()
return user
user.set_password 로 비밀번호를 수정해주고 저장을 하면 해슁된 비밀번호로 저장이 된다!
또한 extra_kwargs 를 통해서 리턴된 데이터를 안보이게 할 수 있다! 반대로 read_only 도 존재한다.
read_only 는 시리얼라이즈를 할때 데이터가 개속해서 생성되거나 수정되거나, 필수로 입력해야 하는 값들에 대한 오류가 있을 때 사용이 가능한 것 같다.
validate , create ,update 와 관련된 내용은 내일 개인적으로 작업을 진행해보고, 정리를 다시 해봐야겠다.
그리고 내일부터 주말동안 프론트와 연결하는 작업도 진행할 예정이다!!