Функция отправки сообщения APIView не добавляется в базу данных
У меня есть моя следующая модель:
class Follow(models.Model):
user = models.ForeignKey(
"User", related_name="follower", on_delete=models.CASCADE)
following_user = models.ForeignKey(
"User", related_name="following", blank=True, on_delete=models.CASCADE)
date_followed = models.DateTimeField(editable=False, default=timezone.now)
class Meta:
constraints = [
models.UniqueConstraint(
fields=['user', 'following_user'], name="unique_followers")
]
ordering = ["-date_followed"]
def __str__(self):
return f"{self.user.username} follows {self.following_user.username}"
и сериализатор:
class FollowSerializer(serializers.ModelSerializer):
class Meta:
model = Follow
fields = ['user', 'following_user', 'date_followed']
Затем в моих представлениях у меня есть APIView, который создает следующее:
class FollowingView(APIView):
permission_class = [permissions.IsAuthenticated]
queryset = Follow.objects.all()
serializer_class = FollowSerializer
def post(self, request):
user = request.data.get('user')
following_user = request.data.get('to_user')
try:
follow = Follow.objects.create(
user=user, following_user=following_user)
follow.save()
serializer = FollowSerializer(follow)
print(serializer.data)
def __str__(self):
return f"{self.request.username} follows {self.following_user_id.username}"
return Response(serializer.data, status=status.HTTP_201_CREATED)
except:
return Response(status=status.HTTP_400_BAD_REQUEST)
Не уверен, что не так. Я могу вывести параметры, но похоже, что функция создания не проходит.
Благодарю за любую помощь!
Вам необходимо удалить метод .save()
, который используется с object.create
.
object.create
используется для сохранения объекта данных в таблице, поэтому нет необходимости .save()
follow = Follow.objects.create(user=user, following_user=following_user)
serializer = FollowSerializer(follow)
print(serializer.data)
Вы также можете сохранить данные и сериализовать их с помощью APIView()
подхода, как это
def post(self, request):
serializer = FollowSerializer(data=request.data)
print(serializer.is_valid()) ## for debug
print(serializer.errors) ## for debug
if serializer.is_valid():
serializer.save()
return Response({'msg':'Data Created'}, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
class FollowSerializer(serializers.ModelSerializer):
user = serializers.PrimaryKeyRelatedField(many=False, read_only=True)
following_user = serializers.PrimaryKeyRelatedField(many=False, read_only=True)
class Meta:
model = Follow
fields = ['user', 'following_user', 'date_followed']
и внутри вашего представления просто проверьте ваш сериализатор и сохраните его со связанными полями
class FollowingView(APIView):
permission_class = [permissions.IsAuthenticated]
queryset = Follow.objects.all()
serializer_class = FollowSerializer
def post(self, request):
user = request.data.get('user')
following_user = request.data.get('to_user') # check if it's correct
try:
user = User.objects.get(id=user)
following_user = User.objects.get(id=following_user)
serializer = FollowSerializer(request.data)
if serializer.is_valid():
serializer.save(
user=user,
following_user=following_user
)
def __str__(self):
return f"{self.request.username} follows {self.following_user_id.username}"
return Response(serializer.data, status=status.HTTP_201_CREATED)
except:
return Response(status=status.HTTP_400_BAD_REQUEST)
Первая проблема в этой строке:
following_user = request.data.get('to_user')
В вашем сериализаторе нет такого поля to_user
, поэтому значение, которое вы получаете из запроса, равно None
. Замените переменную соответствующим образом.
following_user = request.data.get('following_user')
Во-вторых, вы пытаетесь создать свои Follow
объекты непосредственно с идентификаторами вместо экземпляров пользователей, просто получите экземпляры пользователей перед попыткой создания объекта.
from rest_framework import permissions
from core.models import Follow
from core.api.serializers import FollowSerializer
from django.contrib.auth import get_user_model
class FollowingView(APIView):
permission_class = [permissions.IsAuthenticated]
queryset = Follow.objects.all()
serializer_class = FollowSerializer
def post(self, request):
user_id = request.data.get('user')
following_user_id = request.data.get('following_user')
user = get_object_or_404(get_user_model(), id=user_id)
following_user = get_object_or_404(get_user_model(), id=following_user_id)
try:
follow = Follow.objects.create(
user=user, following_user=following_user)
follow.save()
serializer = FollowSerializer(follow)
print(serializer.data)
def __str__(self):
return f"{self.request.username} follows {self.following_user_id.username}"
return Response(serializer.data, status=status.HTTP_201_CREATED)
except:
return Response(status=status.HTTP_400_BAD_REQUEST)
Edit: См. ответ @Ankit Tiwari о том, как правильно использовать сериализатор для проверки данных