Я бы хотел, чтобы пользователи могли выполнять запрос POST для создания поста в блоге и использовать topic name
вместо topic id
в качестве опции.
Минимальная модель может выглядеть следующим образом.
models.py
class Topic(models.Model):
name = models.CharField(max_length=30, unique=True)
description = models.CharField(max_length=100)
class Post(models.Model):
name = models.CharField(max_length=30)
topic = models.ForeignKey(Topic, on_delete=models.PROTECT)
created_on = models.DateTimeField(blank=True, auto_now_add=True, editable=False)
Теперь есть 2 возможных подхода, которые я рассмотрел:
1) Обеспечьте простоту просмотра.
views.py
class PostList(ListCreateAPIView):
queryset = Post.objects.all()
serializer_class = PostSerializer
serializers.py
class PostSerializer(serializers.ModelSerializer):
topic_name = serializers.CharField()
class Meta:
model = Topic
fields = ('name', 'topic_name', 'created_on')
read_only_fields = ('created_on',)
def validate_topic_name(self, value):
"""Verify that the topic exists."""
if not Topic.objects.filter(name=value).exists():
raise serializers.ValidationError("Specified Topic Name does not exist!")
else:
return value
def create(self, validated_data):
"""Create a Post."""
topic_name = validated_data.pop('topic_name', None)
topic = Topic.objects.get(name=topic_name)
return Post.objects.create(topic=topic, **validated_data)
2) Держите сериализаторы простыми.
views.py
class PostList(ListCreateAPIView):
queryset = Post.objects.all()
def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
if not serializer.is_valid():
return Response(
serializer.errors, status=status.HTTP_400_BAD_REQUEST)
topic = get_object_or_404(Topic, name=serializer.data['topic_name'])
post = Post.objects.create(
name=serializer.data['name'],
topic=topic)
return Response({'name': serializer.data['name'], 'description': serializer.data['topic_name']},
status=status.HTTP_201_CREATED)
serializers.py
class PostSerializer(serializers.ModelSerializer):
topic_name = serializers.CharField()
class Meta:
model = Topic
fields = ('name', 'topic_name', 'created_on')
read_only_fields = ('created_on',)
Мой вопрос:
- Куда мне поставить сложность? В сериализаторе в просмотрах?
- Есть ли лучший способ продолжить?