色々調べてもフロントのコードが乗ってなかったり。シリアライザーでコード書いていたり、ビューで書いていたりでハマったので記録しておく。
Django==4.1.5
djangorestframework==3.14.0
followUser がフォローしているTopicをManyToManyで管理する
models.py
class Topic(models.Model):
title = models.CharField(max_length=255, unique=True)
description = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
class FollowTopic(models.Model):
followUser = models.OneToOneField(
settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="followUser"
)
topics = models.ManyToManyField(Topic, related_name="followedTopics", blank=True)
views.py
実際にはユーザーを確認する手順が必要になると思う。
Firebaseで認証しているのでユーザーIDはそこから取得している。
class FollowTopicView(ModelViewSet):
queryset = FollowTopic.objects.all()
serializer_class = FollowSerializer
def get_object(self):
q = FollowTopic.objects.get(pk=self.kwargs["pk"])
return q
def update(self, request, *args, **kwargs):
# フロントから送ってきたデータを取り出す
data = request.data
# 狙いのobjectsを取り出す。getの中身はPostの仕方によってになると思う
update_follow = FollowTopic.objects.get(pk=self.kwargs["pk"])
update_follow.save
# いったんManyToManyをすべてクリアする
update_follow.topics.clear()
# Topicのidからobjectを取得して、addで追加していく
for topic in data["topics"]:
topic_obj = Topic.objects.get(pk=topic)
update_follow.topics.add(topic_obj)
serializer = FollowSerializer(update_follow)
return Response(serializer.data)
def get_queryset(self):
try:
auth = FirebaseAuthentication()
user, _ = auth.authenticate(self.request)
# get_or_createにするので初めてクエリーするときに1つIDが発行されるのでエラーにならない
queryset = FollowTopic.objects.get_or_create(followUser_id=user.id)
return queryset
except:
print("FollowTopic except")
serializers.py
class FollowSerializer(serializers.ModelSerializer):
class Meta:
model = FollowTopic
fields = [
"id",
"followUser_id",
"topics",
]
depth = 1
Next.jsでPutする場合
putするURLにFollowTopicのidを指定しているので、ユーザーは固定されている(Djangoで確認はすべき)。
実際にデータとして送る必要があるのはtopicsにリストの形でIdを入れるだけ。
const FollowTopicBtn = (token: string) => {
const ids =
followData &&
followData[0].topics.map((t: any) => {
return t.id;
});
const data = {
topics: [...ids, topic.id],
};
const res = axios
.put(`your URL/${followData[0].id}/`,
data,
{
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${token}`,
},
}
)
.then((response) => {
return response.data;
})
.catch((error) => {
console.log(error);
})
.finally(() => {
//更新
mutate(true);
});
};
参考
Django Rest Framework API #22 / Many To Many Relationship , Nested Data
https://www.youtube.com/watch?v=NCBxyw6rDds