一旦我将 django 休息框架指向一个目录,我就会尝试使用它来执行多个 POST 事件。我的想法是,我将指定国家/地区和包含多个图像的目录。然后,API 必须转到该目录,并将该目录中的每个图像以及每个图像的文件名中提供的更多详细信息发布到数据库。按照互联网上的一些指示,我设法构建了一个小模型和框架,看起来除了一件事之外它可以工作。默认的rest API页面不支持列表的HTML输入。
我想知道我的时间是否应该更好地花在使 API 页面符合我的要求,或者我是否应该构建自己的 HTML 界面。
或者更直接
使用 Django 和 Django REST Framework 将多个图像(每个图像是数据库中的一个单独实例)上传到数据库的最快(也是最简单)的方法是什么?
models.py:
from django.db import models
# Create your models here.
class Tiles(models.Model):
image = models.ImageField(blank=True, null=True)
lat = models.FloatField(blank=True, null=True)
lng = models.FloatField(blank=True, null=True)
country = models.CharField(blank=True, null=True, max_length=10)
solar = models.FloatField(blank=True, null=True)
wind = models.FloatField(blank=True, null=True)
HV = models.FloatField(blank=True, null=True)
class Meta:
verbose_name_plural = "Tiles"
views.py
from django.shortcuts import render
from rest_framework import viewsets
from .serializers import FileListSerializer
from rest_framework import parsers
from .models import Tiles
# Create your views here.
def index(request):
return render(request, 'main/index.html')
class TileViewSet(viewsets.ModelViewSet):
serializer_class = FileListSerializer
parser_classes = (parsers.MultiPartParser, parsers.FormParser,)
queryset = Tiles.objects.all()
序列化器.py
from rest_framework import serializers
from .models import Tiles
import mercantile
class FileListSerializer(serializers.Serializer):
image = serializers.ListField(
child=serializers.FileField(max_length=100000,
allow_empty_file=False,
use_url=False)
)
country = serializers.CharField(max_length=10)
# The create function below overrides the Django default create function to populate multiple fields using the image name
def create(self, validated_data):
country = validated_data.pop('country')
image = validated_data.pop('image')
for img in image:
path = img.path
path = path.split('/')[-1]
path = path.split('.')[0]
x, y, z = path.split('-')
coords = mercantile.ul(int(x), int(y), int(z))
tile = Tiles.objects.create(image=img, country=country, lat=coords.lat, lng=coords.lng, **validated_data)
return tile
class TileSerializer(serializers.ModelSerializer):
class Meta:
model = Tiles
fields = '__all__'
最佳答案
我已经找到了解决这个问题的方法。希望这可以帮助某人。在serializers.py中,我将ListField更改为FilePathField,它可以将目录作为输入。
新的序列化器.py:
from rest_framework import serializers
from .models import Tiles
import mercantile
import os
BASE_DIR = os.path.dirname((os.path.dirname(os.path.abspath(__file__))))
class FileListSerializer(serializers.Serializer):
# The following FilePathField is named image but refers to a directory containing multiple images
image = serializers.FilePathField(path=(os.path.join(BASE_DIR, 'opt_rec_master_img_dir')), allow_files=False, allow_folders=True)
country = serializers.CharField(max_length=10)
# The following variables for each instance are generated automatically upon clicking create
# They are included here so that the DRF auto generated json output includes this information
lat = serializers.FloatField(read_only=True)
lng = serializers.FloatField(read_only=True)
solar = serializers.FloatField(read_only=True)
wind = serializers.FloatField(read_only=True)
HV = serializers.FloatField(read_only=True)
# This function overrides the default create function to populate multiple fields given a directory full of images.
def create(self, validated_data):
country = validated_data.pop('country')
image = validated_data.pop('image')
directory = image.split('/')[-1]
for img in os.listdir(image):
path = img.split('.')[0]
x, y, z = path.split('-')
coords = mercantile.ul(int(x), int(y), int(z))
tile = Tiles.objects.create(image=os.path.join('opt_rec_master_img_dir', directory, img), country=country, lat=coords.lat, lng=coords.lng)
return tile
class Meta:
model = Tiles
View .py
from django.shortcuts import render
from rest_framework import viewsets
from .serializers import FileListSerializer
from .models import Tiles
from django.core.files.images import ImageFile
from rest_framework.utils.encoders import JSONEncoder
from rest_framework.renderers import JSONRenderer, BrowsableAPIRenderer
# Create your views here.
# def index(request):
# return render(request, 'main/index.html')
#
# JSONEncoder and JSONRenderer have been overriden here to serialize the image path rather than image byte data
class OREncoder(JSONEncoder):
def default(self, obj):
if isinstance(obj, ImageFile):
return obj.path
return super().default(obj)
class ORRenderer(JSONRenderer):
encoder_class = OREncoder
class TileViewSet(viewsets.ModelViewSet):
serializer_class = FileListSerializer
queryset = Tiles.objects.all()
renderer_classes = [ORRenderer, BrowsableAPIRenderer]
关于python - 如何通过django Rest框架一键发布目录中的多张图片,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57759826/