2017-06-05 55 views
1

对不起,我有一个问题,任何人都可以帮助我。Django Rest框架帖子嵌套使用带请求的文件模块示例

我有车型,如:

from django.db import models 
from django.contrib.auth.models import User 
import uuid 


def uuid_generator(): 
    return str(uuid.uuid4()) 


class Profile(models.Model): 
    user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='profile_user') 
    mobile = models.CharField(max_length=20) 
    alamat = models.TextField(blank=True) 
    phone = models.CharField(max_length=20, blank=True) 
    foto = models.ImageField(upload_to='profile', blank=True) 

    def __str__(self): 
     return self.user.username 


class Rumah(models.Model): 
    JENIS_CHOICES = (
     ('rumah', 'Rumah besar'), 
     ('petakan', 'Rumah petakan'), 
     ('apartement', 'Apartement'), 
     ('kost', 'Kost-Kostan') 
    ) 

    WAKTU_CHOICES = (
     ('bulanan', 'Bulanan'), 
     ('tahunan', 'Tahunan'), 
    ) 

    STATUS_CHOICES = (
     ('tersedia', 'Tersedia'), 
     ('terisi', 'Sudah Terisi'), 
     ('ditutup', 'Di Tutup'), 
    ) 

    pemilik = models.ForeignKey(User, on_delete=models.CASCADE, related_name='rumah_user') 
    kode = models.CharField(unique=True, max_length=150) 
    jenis = models.CharField(max_length=12, choices=JENIS_CHOICES, default='rumah') 
    waktu = models.CharField(max_length=10, choices=WAKTU_CHOICES, default='bulanan') 
    harga = models.PositiveIntegerField() 
    alamat = models.TextField() 
    status = models.CharField(max_length=10, choices=STATUS_CHOICES, default='tersedia') 
    keterangan = models.TextField(blank=True) 

    def __str__(self): 
     return self.kode 

    def save(self, *args, **kwargs): 
     self.kode = uuid_generator() 
     super(Rumah, self).save(*args, **kwargs) 


class Foto(models.Model): 
    rumah = models.ForeignKey(Rumah, on_delete=models.CASCADE, related_name='foto_rumah') 
    penampakan = models.ImageField(upload_to='penampakan', blank=True) 
    keterangan = models.TextField(blank=True) 

    def __str__(self): 
     return self.rumah.kode 

注:的Rumah英语和图片图片英文。

我有这样一个观点:

from django.contrib.auth.models import User 
from produk.models import Profile, Rumah, Foto 
from .serializers import UserSerializer, ProfileSerializer, RumahSerializer, FotoSerializer 
from .permissions import IsOwnerOrReadOnly, IsHasProfile, IsRumahOrReadOnly 
from rest_framework import mixins 
from rest_framework import generics 
from rest_framework import permissions 


class UserList(generics.ListAPIView): 
    queryset = User.objects.all() 
    serializer_class = UserSerializer 


class UserDetail(generics.RetrieveAPIView): 
    queryset = User.objects.all() 
    serializer_class = UserSerializer 


class ProfileList(generics.ListCreateAPIView): 
    queryset = Profile.objects.all() 
    serializer_class = ProfileSerializer 
    permission_classes = (permissions.IsAuthenticatedOrReadOnly,) 

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


class ProfileDetail(generics.RetrieveUpdateDestroyAPIView): 
    permission_classes = (permissions.IsAuthenticatedOrReadOnly, IsOwnerOrReadOnly) 
    queryset = Profile.objects.all() 
    serializer_class = ProfileSerializer 


class RumahList(generics.ListCreateAPIView): 
    queryset = Rumah.objects.all() 
    serializer_class = RumahSerializer 
    permission_classes = (permissions.IsAuthenticatedOrReadOnly,) 

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


class RumahDetail(generics.RetrieveUpdateDestroyAPIView): 
    queryset = Rumah.objects.all() 
    serializer_class = RumahSerializer 
    permission_classes = (permissions.IsAuthenticatedOrReadOnly, IsOwnerOrReadOnly) 


class FotoList(generics.ListCreateAPIView): 
    queryset = Foto.objects.all() 
    serializer_class = FotoSerializer 
    permission_classes = (permissions.IsAuthenticatedOrReadOnly,) 


class FotoDetail(generics.RetrieveUpdateDestroyAPIView): 
    queryset = Foto.objects.all() 
    serializer_class = FotoSerializer 
    permission_classes = (permissions.IsAuthenticatedOrReadOnly, IsRumahOrReadOnly) 

我有一个序列化,如:

from django.contrib.auth.models import User 
from rest_framework import serializers 
from produk.models import Profile, Rumah, Foto 


class UserSerializer(serializers.HyperlinkedModelSerializer): 
    rumah_user = serializers.HyperlinkedRelatedField(many=True, view_name='rumah-detail', read_only=True) 
    profile_user = serializers.HyperlinkedRelatedField(many=False, view_name='profile-detail', read_only=True) 

    class Meta: 
     model = User 
     fields = ('id', 'username', 'email', 'is_active', 'rumah_user', 'profile_user') 


class ProfileSerializer(serializers.ModelSerializer): 
    user = serializers.ReadOnlyField(source='user.username') 

    class Meta: 
     model = Profile 
     fields = ('id', 'user', 'alamat', 'mobile', 'phone', 'foto') 


class FotoSerializer(serializers.ModelSerializer): 
    # rumah = serializers.ReadOnlyField(source='rumah.kode') 

    class Meta: 
     model = Foto 
     fields = ('id', 'rumah', 'penampakan', 'keterangan') 


class RumahSerializer(serializers.ModelSerializer): 
    pemilik = serializers.ReadOnlyField(source='pemilik.username') 
    #foto_rumah = serializers.HyperlinkedRelatedField(many=True, view_name='foto-detail', read_only=True) 
    foto_rumah = FotoSerializer(many=True) 

    class Meta: 
     model = Rumah 
     fields = ('id', 'pemilik', 'jenis', 'waktu', 'harga', 'alamat', 'status', 'keterangan', 'foto_rumah') 

    def create(self, validated_data): 
     fotos_data = validated_data.pop('foto_rumah') 
     print(validated_data) 
     rumah = Rumah.objects.create(**validated_data) 
     for foto_data in fotos_data: 
      Foto.objects.create(rumah=rumah, **foto_data) 
     return rumah 

当我尝试将其与请求模块,如:

import requests 
from requests.auth import HTTPBasicAuth 

url = 'http://127.0.0.1:8000/rumah/' 

files = {'penampakan': open('C:\\Users\\yanz\\Pictures\\Campuran\\test.png', 'rb')} 
data = { 
     "pemilik": "admin", 
     "jenis": "rumah", 
     "waktu": "bulanan", 
     "harga": 3, 
     "alamat": "r", 
     "status": "tersedia", 
     "keterangan": "4", 
     "foto_rumah": [ 
      { 
       "penampakan": files, 
       "keterangan": "a" 
      } 
     ] 
    } 
r = requests.post(url, data=data, files=files, auth=HTTPBasicAuth('admin', 'password123')) 

print(r.text) 

结果:

{"id":11,"pemilik":"admin","jenis":"rumah","waktu":"bulanan","harga":3,"alamat":"r","status":"tersedia","keterangan":"4","foto_rumah":[]} 

Foto(foto_rumah)来自模型Foto的数据未保存。解决方案是什么?如何使用文件发布嵌套数据?

谢谢...

+0

请调试'RumahSerializer'或'FotoSerializer'序列化程序,我猜你丢失了图片数据,因为表单编码。 –

回答

0

嵌套序列化器不适用于表单编码数据。 上传图像仅适用于开箱即用的表单编码数据。

我想你需要在特定的非嵌套入口点上传图片或在JSON中使用base64编码文件。 我记得我已经看到第三方处理base64文件,但无法再找到它。

+0

好的,谢谢先生。 –

相关问题