작성
·
181
0
안녕하세요 강사님, 저는 강사님 코드에서 조금씩 수정하여 서버를 띄워보았는데, PostDetail 보여주는 부분에서 계속 오류가 생겨서요,
TypeError: Object of type User is not JSON serializable [21/Oct/2023 21:14:51] "GET /api/post/2/ HTTP/1.1" 500 120254
이렇게 오류가 뜨는데 왜 이럴까요? ㅠㅠ
이전/다음 포스팅 보여주기 전에 포스팅 하나의 상세페이지 띄워주는 것까지는 정상적으로 확인이 됐었습니다.
api/views.py
# Create your views here.
class ApiPostLV(BaseListView):
model = Post
def get_queryset(self):
queryset = super().get_queryset()
return queryset.order_by('-create_dt')
def render_to_response(self, context, **response_kwargs):
qs = context['object_list']
postList = [obj_to_post(obj) for obj in qs]
return JsonResponse(data=postList, safe=False, status=200)
class ApiPostDV(BaseDetailView):
model = Post
def render_to_response(self, context, **response_kwargs):
obj = context['object']
post = obj_to_post(obj)
post['prev'], post['next'] = prev_next_post(obj)
return JsonResponse(data=post, safe=True, status=200)
api/views_util.py
def obj_to_post(obj):
post = dict(vars(obj))
if obj.create_dt:
post['create_dt'] = obj.create_dt.strftime('%Y-%m-%d %H:%M')
else:
post['create_dt'] = ''
if obj.modify_dt:
post['modify_dt'] = obj.modify_dt.strftime('%Y-%m-%d %H:%M')
else:
post['modify_dt'] = ''
if obj.tags:
post['tags'] = [tag.name for tag in obj.tags.all()]
else:
post['tags'] = []
if obj.owner:
post['owner'] = obj.owner.username
else:
post['owner'] = 'Anonymous'
del post['_state']
return post
def prev_next_post(obj):
try:
prevObj = obj.get_prev()
prevDict = {'id' : prevObj.id, 'title' : prevObj.title, 'description' : prevObj.description, 'create_dt' : prevObj.create_dt, 'owner' : prevObj.owner}
except obj.DoesNotExist as e:
prevDict = {}
try:
nextObj = obj.get_next()
nextDict = {'id' : nextObj.id, 'title' : nextObj.title, 'description' : nextObj.description, 'create_dt' : nextObj.create_dt, 'owner' : nextObj.owner}
except obj.DoesNotExist as e:
nextDict = {}
return prevDict, nextDict
blog/models.py
class Post(models.Model):
title = models.CharField(verbose_name='TITLE', max_length=50)
# verbose_name : 칼럼에 대한 별칭
description = models.CharField('DISCRIPTION', max_length=100, blank=True, help_text='simple description text.')
content = models.TextField('CONTENT')
create_dt = models.DateTimeField('CREATE DATE', auto_now_add=True)
modify_dt = models.DateTimeField('MODIFY DATE', auto_now=True)
tags = TaggableManager(blank=True)
owner = models.ForeignKey(get_user_model(), on_delete=models.CASCADE, verbose_name='OWNER', blank=True, null=True)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('blog:post_detail', args=(self.id,))
def get_prev(self):
return self.get_previous_by_create_dt()
def get_next(self):
return self.get_next_by_create_dt()
PostDetail.vue
<template>
<v-container class="white">
<v-row align="center" justify="center">
<!-- align 속성은 위아래, justify 속성은 좌우 위치 조정 -->
<v-col cols="12" lg="10">
<!-- <v-card class="pa-2" outlined tile> -->
<h1>{{ post.title }}</h1>
<div>
<h3>{{ post.description }}</h3>
</div>
<div>
<p style="margin: 5px 0;">작성일자 : {{ post.create_dt }} 최종수정 : {{ post.modify_dt }}</p>
<p style="margin: 5px 0;">written by {{ post.owner }}</p>
</div>
<v-divider></v-divider>
<!-- </v-card> -->
</v-col>
</v-row>
<v-row align="start" justify="center">
<v-col cols="12" lg="10">
<!-- <v-card class="pa-2" outlined tile> -->
<p style="white-space: pre-wrap;">
{{ post.content }}</p>
<div>
<strong>TAGS:</strong>
<v-chip class="ma-2" outlined v-for="(tag, index) in post.tags" :key="index">{{ tag }}</v-chip>
</div>
<v-divider></v-divider>
<!-- </v-card> -->
</v-col>
</v-row>
<v-row align="center" justify="center">
<v-col cols="12" lg="10">
<v-card class="pa-2" outlined tile>
<v-row>
<!-- 왼쪽에 다음 글 문구 배치 -->
<v-col align="center" cols="2">
<p>이전 글</p>
</v-col>
<!-- 오른쪽에 다음 글 제목 문구 배치 -->
<v-col cols="10">
<div>
<h3 v-if="post.prev" @click="fetchPostDetail(post.prev.id)">{{ post.prev.title }}</h3>
<p v-if="post.prev" @click="fetchPostDetail(post.prev.id)">{{ post.prev.description }}</p>
</div>
</v-col>
</v-row>
</v-card>
<v-card class="pa-2" outlined tile>
<v-row>
<!-- 왼쪽에 다음 글 문구 배치 -->
<v-col align="center" cols="2">
<p>다음 글</p>
</v-col>
<!-- 오른쪽에 다음 글 제목 문구 배치 -->
<v-col cols="10">
<div>
<h3 v-if="post.next" @click="fetchPostDetail(post.next.id)">{{ post.next.title }}</h3>
<p v-if="post.next" @click="fetchPostDetail(post.next.id)">{{ post.next.description }}</p>
</div>
</v-col>
</v-row>
</v-card>
</v-col>
</v-row>
</v-container>
</template>
<script>
import axios from "axios";
export default {
name: "PostDeatail",
data: () => ({
post: {},
}),
created() {
console.log("created()...");
const postId = 2;
this.fetchPostDetail(postId);
},
methods: {
fetchPostDetail(postId) {
console.log("fetchPostDetail()...", postId);
axios.get(`/api/post/${postId}/`)
.then(res =>{
console.log("POST DETAIL GET RES", res);
this.post = res.data;
})
.catch(err => {
console.log("POST DETAIL GET ERR_RESPONSE", err.response);
alert(err.response.status + ' ' + err.response.statusText);
});
}
}
}
</script>
<style scoped>
</style>
계속 다시 코드를 짜보았는데도 어디서 오류가 나는 것인지 모르겠어서요 ㅠㅠ.....
감사합니다 .. ㅜㅜ
답변 2
0
prevObj.owner 에는 User 객체가 들어 있습니다. 이 User 객체를 serialize 하는 과정에 에러가 난 것입니다.
해결방법은 User 객체 전체를 보내는 것이 아니라, User 객체의 username 속성만 보내면 됩니다.
prevDict = {'id' : prevObj.id, ..., 'owner' : prevObj.owner.username}
0
독자님. 혹시 저의 원래 코드에서는 에러가 발생 않나요?
그렇다면 독자님의 수정한 코드에서, 아래 에러 메세지와 관련 코드가 있는지 확인 바랍니다.
TypeError: Object of type User is not JSON serializable
말씀해주신대로 강사님이랑 똑같이 코드 수정 후에 하나씩 바꾸면서 진행 했더니 오류가 난 부분을 찾았습니다 !
prev_next_post() 메서드에서
prevDict = {'id' : prevObj.id, 'title' : prevObj.title, 'description' : prevObj.description, 'create_dt' : prevObj.create_dt.strftime('%Y-%m-%d %H:%M'), 'owner' : prevObj.owner}
'owner' : prevObj.owner 이 부분에서 오류가 나는 듯 합니다. 이것만 제거하면 잘 되더라구요.
그런데 왜 여기서 저런 에러가 나는 건지 모르겠습니다 ㅜㅜ
주말에도 답변해주시고 정말 감사합니다 강사님 !! ㅠㅠ