首页 > 解决方案 > Django rest框架多对一关系

问题描述

我想显示与任务相关的附件列表。如何传递任务的pk(uuid)?到目前为止,我试过这个:

模型.py

class Task(Timestamp):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, unique=True, editable=False)
    title = models.CharField(max_length=50)
    description = models.TextField()

    def __str__(self):
        return self.title

class Attachment(Timestamp):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, unique=True, editable=False)
    task = models.ForeignKey(Task, on_delete=models.CASCADE)
    attachment = models.FileField(upload_to='tasks-attachments/%Y-%m-%d/')

    def __str__(self):
        return self.task.title + " attachment"

序列化程序.py

class AttachmentSerializer(serializers.ModelSerializer):
    
    class Meta:
        model = Attachment
        fields = [
            'id',
            'task',
            'created_at',
            'updated_at',
            'attachment'
        ]

视图.py

class AttachmentsView(generics.ListCreateAPIView):

    serializer_class = AttachmentSerializer

    def get_queryset(self):
        return Attachment.objects.filter(task=task__id)

网址.py

urlpatterns = [
    path('tasks/', TasksView.as_view()),
    path('tasks/<uuid:pk>', TaskView.as_view()),
    path('tasks/<uuid:pk>/attachments/', AttachmentsView.as_view())
    ]

标签: pythondjangodjango-rest-frameworkforeign-keys

解决方案


首先添加related_name到模型上的任务字段,已经Django 完成的默认命名,但最好添加你的。Attachmentrelated_name

related_name是反向关系的名称,因此您可以从引用的对象中获取相关对象,因此应该是:

task = models.ForeignKey(Task, on_delete=models.CASCADE, related_name='attachments')

这就是为什么它具有attachments我们稍后将在task对象中使用它的值的原因,因此正确的命名将消除任何混淆。

最后,如果您将使用 ModelSerializer,则创建一个任务序列化程序并添加attachments到它,fields以便它将相关对象与其他任务字段一起序列化。

例如:

class TaskSerializer(serializers.ModelSerializer):
    attachments = AttachmentSerializer(read_only=True, many=True)

    class Meta:
        model = Task
        fields = ['id', 'title', 'attachments']

推荐阅读