【问题标题】:How to create views.py for multiple models including many-to-many如何为多个模型创建views.py,包括多对多
【发布时间】:2021-09-26 01:59:40
【问题描述】:

我是 Python 和 DjangoRestFramework 的新手。我正在尝试创建带有图像标记的图像上传系统。 “标签”与“图像”具有多对多的关系。表单位于前端的 React.js 中。我试图了解如何为此编写视图。我在网上没有看到明确的解决方案。

这里是上传/models.py

from django.db import models
from django.db.models.fields import UUIDField
from django.contrib.postgres.functions import RandomUUID


def upload_path(instance, filename):
    return '/'.join(['images', str(instance.contributor), str(instance.caption), str(instance.date_created), filename])


class Image(models.Model):
    image = models.ImageField(upload_to=upload_path)
    contributor = models.ForeignKey(
        'accounts.User', related_name='+', on_delete=models.CASCADE, default='user0')
    caption = models.CharField(max_length=100)
    date_created = models.DateTimeField(auto_now_add=True, null=True)
    id = UUIDField(primary_key=True, default=RandomUUID, editable=False)
    theme = models.CharField(max_length=10)

class Tags(models.Model):
    tag = models.ManyToManyField(Image, through='Junction')

class Junction(models.Model):
    image = models.ForeignKey(Image, on_delete=models.CASCADE)
    tags = models.ForeignKey(Tags, on_delete=models.CASCADE)

上传/serializers.py

from rest_framework import serializers
from .models import Image, Theme, Tags, Junction


class TagsSerializer(serializers.ModelSerializer):
    tags = serializers.PrimaryRelatedKeyField(
        queryset=Image.object.all(), many=True)

    class Meta:
        model = Tags
        fields = ('Tags')


class ImageSerializer(serializers.ModelSerializer):
    tags_list = TagsSerializer(many=True, read_only=True)

    class Meta:
        model = Image
        fields = ('image', 'contributor', 'caption', 'date_created', 'id')

class JunctionSerializer(serializers.ModelSerializer):
    class Meta:
        model = Junction
        fields = ('image', 'theme', 'tags')

以下是 upload/views.py 的两种可能解决方案:

from django.shortcuts import render
from django.http import HttpResponse
from rest_framework import viewsets
from .serializers import JunctionSerializer
from .models import Image, Tags, Junction

#SOLUTION_1:
class JunctionView(viewsets.ModelViewSet):
    serializer_class = JunctionSerializer
    query_set = Junction.objects.all()

    def get_context_data(self, request, *args, **kwargs):
            image = request.data['cover']
            tags = request.data['tags']
       
            Junction.objects.create(image=image, tags=tags)
            return HttpResponse({'message': 'Successful Upload'}, status=200)


#SOLUTION_2
class JunctionView():
    
    ????

    def get_context_data(self, **kwargs):
        context = super(JunctionView, self).get_context_data(**kwargs)
        context['image'] = Image.objects.all()
        context['tags'] = Tags.objects.all()
        return context

是否需要调用上下文?我研究的第二个解决方案并不特定于 Django REST Framework,我认为..

【问题讨论】:

  • 你可以为Image创建一个模型序列化器,它接受一个标签列表
  • 我刚刚复制了上面的serializers.py代码。我相信我做到了..

标签: python django django-models django-rest-framework django-views


【解决方案1】:

一种方法是为图像创建ModelViewSet,因为您主要负责管理图像。

class ImageViewSet(viewsets.ModelViewSet):
    serializer_class = ImageSerializer
    query_set = Image.objects.all()

然后使用您的序列化程序,只需修改您的序列化程序以处理与直通模型的 m2m 关系,如 here 所述。所以像:

class ImageSerializer(serializers.ModelSerializer):
    tags_list = TagsSerializer(many=True, read_only=True)

    class Meta:
        model = Image
        fields = ('image', 'contributor', 'caption', 'date_created', 'id')

    def create(self, validated_data):
        tags_list = validated_data.pop('tags_list')
        instance = super().create(validated_data)

        for tag in tags_list:
            Junction.objects.create(image=instance, tag=tag)

这没有经过测试,所以它可能会在这里和那里有一些问题,但这是要点。

【讨论】:

  • 谢谢@bdbd。如果我遵循您的建议,我是否不需要def get_context_data 并在ImageView 中返回HttpResponse
  • 对不起,我想我必须重新发布这个问题,因为我必须让我的模型更复杂才能上传多张图片。我会把链接复制到这里。
  • @Jie-LiangLin 如果回答了这个问题,请采纳。
猜你喜欢
  • 1970-01-01
  • 2020-03-26
  • 1970-01-01
  • 2020-09-28
  • 2012-06-14
  • 2011-10-23
  • 2016-01-10
  • 2021-12-06
  • 1970-01-01
相关资源
最近更新 更多