【问题标题】:Django Rest Framework: Serialize multiple images to one post inDjango Rest Framework:将多个图像序列化为一篇文章
【发布时间】:2019-09-17 03:03:03
【问题描述】:

我正在尝试能够序列化和上传多个图像以与每个帖子相关联。

这是我的models.py

from django.conf import settings
from django.db import models
from django.db.models.signals import pre_save
from .utils import unique_slug_generator


class Painting(models.Model):
    user                        = models.ForeignKey(settings.AUTH_USER_MODEL, default="", on_delete=models.CASCADE)
    title                       = models.CharField(blank=False, null=False, default="", max_length=255)
    slug                        = models.SlugField(blank=True, null=True)
    style                       = models.CharField(blank=True, null=True, default="", max_length=255)       #need to figure out why there is problem when this is False
    description                 = models.TextField(blank=True, null=True, default="")
    size                        = models.CharField(blank=True, null=True, default="", max_length=255)
    artist                      = models.CharField(blank=True, null=True, default="", max_length=255)
    price                       = models.DecimalField(blank=True, null=True, decimal_places=2, max_digits=20)
    available                   = models.BooleanField(default=True)
    updated                     = models.DateTimeField(auto_now=True, auto_now_add=False)
    timestamp                   = models.DateTimeField(auto_now=False, auto_now_add=True)

    def __str__(self):
        return self.title

    class Meta:
        ordering = ["-timestamp", "-updated"]

class PaintingPhotos(models.Model):
    title                       = models.ForeignKey(Painting, default="", on_delete=models.CASCADE)
    image                       = models.ImageField(upload_to='uploaded_paintings')


def pre_save_painting_receiver(sender, instance, *args, **kwargs):
    if not instance.slug:
        instance.slug = unique_slug_generator(instance)

pre_save.connect(pre_save_painting_receiver, sender=Painting)

我的序列化器.py

from django.contrib.auth import get_user_model, authenticate, login, logout
from django.db.models import Q
from django.urls import reverse
from django.utils import timezone

from rest_framework import serializers

from .models import Painting, PaintingPhotos
User = get_user_model()


class UserPublicSerializer(serializers.ModelSerializer):
    username = serializers.CharField(required=False, allow_blank=True, read_only=True)
    class Meta:
        model = User
        fields = [
            'username',  
            'first_name',
            'last_name',
            ]


# # add PaintingImagesSerializer with the images model here
class PaintingPhotosSerializer(serializers.ModelSerializer):

    class Meta:
        model = PaintingPhotos
        fields =[
            'image'
        ]

#becareful here, if anyone submits a POST with an empty title, it will result in the empty slug, (which will mess up the url lookup since the title is the slug in this case)
#make title a required field in the actual interface, also remember to don't submit s POST with an empty title from the Django restframework directly
class PaintingSerializer(serializers.ModelSerializer):
    url             = serializers.HyperlinkedIdentityField(
                            view_name='paintings-api:detail',
                            read_only=True,
                            lookup_field='slug'
                            )
    user            = UserPublicSerializer(read_only=True)
    owner           = serializers.SerializerMethodField(read_only=True)
    image           = PaintingPhotosSerializer(many=True, read_only=False)

    class Meta:
        model = Painting
        fields = [
            'url',
            'user',
            'title',                    
            'style',                            
            'description',                
            'size',
            'artist',
            'price',                       
            'available',                                
            'updated',
            'timestamp',
            'owner',
            'slug',
            'image',
        ]

    def get_owner(self, obj):

        request = self.context['request']
        if request.user.is_authenticated:
            if obj.user == request.user:
                return True
        return False

我的意见.py

from rest_framework.views import APIView
from rest_framework.parsers import MultiPartParser, FormParser
from rest_framework.response import Response
from rest_framework import generics, permissions, pagination, status

from .models import Painting
from .permissions import IsOwnerOrReadOnly
from .serializers import PaintingSerializer


class PaintingPageNumberPagination(pagination.PageNumberPagination):
    page_size = 5
    page_size_query_param = 'size'
    max_page_size = 20

    def get_paginated_response(self, data):
        author  = False
        user    = self.request.user
        if user.is_authenticated:
            author = True
        context = {
            'next': self.get_next_link(),
            'previous': self.get_previous_link(),
            'count': self.page.paginator.count,
            'author': author,
            'results': data,
        }
        return Response(context)


class PaintingDetailAPIView(generics.RetrieveUpdateDestroyAPIView):
    queryset            = Painting.objects.all()
    serializer_class    = PaintingSerializer
    lookup_field        = 'slug'
    permission_classes  = [IsOwnerOrReadOnly]

class PaintingListCreateAPIView(generics.ListCreateAPIView):
    queryset            = Painting.objects.all()
    serializer_class    = PaintingSerializer
    permission_classes  = [permissions.IsAuthenticatedOrReadOnly]
    pagination_class    = PaintingPageNumberPagination


    def perform_create(self, serializer):
        serializer.save(user=self.request.user)

我收到此错误:

AttributeError:尝试在序列化程序 PaintingSerializer 上获取字段 image 的值时出现 AttributeError。 序列化程序字段可能命名不正确,并且与 Painting 实例上的任何属性或键都不匹配。 原始异常文本为:“Painting”对象没有“image”属性。

我也不确定是否应该创建另一个应用程序来处理所有图像。

提前非常感谢!

【问题讨论】:

  • 您能否使用 HTTP 请求将图像保存到数据库/存储后端?您是否检查了数据库以确保这一点?
  • @JPG 我正在使用 PostgreSQL,你认为这可能吗?你会建议什么替代方案?
  • 文件上传到文件系统,路径存储在数据库中。检查您的 MEDIA_ROOT 设置。您还指定了文件夹“uploaded_pa​​intings”,因此路径将是 MEDIA_ROOT 中的任何内容以及该路径。您可以通过在 Django 管理员中创建带有图像的 PaintingPhotos 对象来测试它是否正常工作。
  • 如果您想坚持 Django 标准,您还应该将类命名为 PaintingPhoto。 Django 会在合适的地方将其复数以显示。这似乎很小,但从长远来看,它可以避免您输入不一致的内容。
  • 我认为这是对您问题的有效答案:stackoverflow.com/questions/48756249/….

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


【解决方案1】:

您的代码看起来与此处的文档非常相似:https://www.django-rest-framework.org/api-guide/relations/#nested-relationships 我看不出到底出了什么问题,但可能是您尚未创建 PaintingPhotos 对象,因此没有模型可以对其进行序列化。我在评论中提到您可以通过 Django 管理员创建它。

【讨论】:

    【解决方案2】:

    大家好,我最终找到了答案。这个 stackoverflow 答案很好地解释了它:Multiple images per Model 我搞砸的地方是没有在我的 PaintingPhotos 模型中将related_name 参数添加到我的照片中。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-08-15
    • 2018-07-23
    • 2013-11-27
    • 2014-04-13
    • 2018-02-17
    • 1970-01-01
    • 2016-09-29
    相关资源
    最近更新 更多