上载文件时,请求和Django“类型错误。预期的pk值,收到InMemoryUploadedFile”

时间:2018-10-25 02:49:03

标签: python django rest django-rest-framework

使用typedef struct header { .... } Header; 发出API(Django 1.11)请求时,我无法发出成功的POST请求,该请求中包含文件和外键。

urls.py

requests

]

models.py

urlpatterns = [
    ....
    url(r'^dataset/visual$', api_views.VisualList.as_view(), name='api-visual'),
    ....

views.py

class Visual(models.Model):

    class Meta:
        verbose_name_plural = "Visuals"

    name = models.CharField(max_length=30)
    description = models.CharField(max_length=75, blank=True, null=True)
    visual = models.FileField(upload_to='visuals/')
    uploaded_at = models.DateTimeField(auto_now_add=True)
    document = models.ForeignKey(Document) <--- LOOK HERE

    def __unicode__(self):
        return self.name

serializers.py

class VisualList(generics.ListCreateAPIView):
    parser_classes = (MultiPartParser, FormParser, FileUploadParser)
    queryset = Visual.objects.all()
    serializer_class = VisualSerializer


class VisualDetail(generics.RetrieveUpdateDestroyAPIView):
    parser_classes = (MultiPartParser, FormParser)
    queryset = Visual.objects.all()
    serializer_class = VisualSerializer

my_requests.py

class VisualSerializer(serializers.ModelSerializer):
    class Meta:
        model = Visual
        fields = '__all__'

当我在 models.py 中设置response = requests.request( 'POST', 'http://127.0.0.1/api/dataset/visual', files={'name': 'Hello World', 'description': 'from API', 'document': 5, 'visual': ('hello_world.html', open('HELLOWORLD.html', 'rb'))}) ,并从document = models.ForeignKey(Document, null=True)参数中删除了document键时,我可以上传文件很好。

但是,当我包含files并将其设为必填字段时,会出现错误消息:

document

看起来好像我正在传递"Incorrect type. Expected pk value, received InMemoryUploadedFile" 的正确类型,是肯定存在的pk的整数。我还有其他将document引用为ForeignKey的模型,并且可以按预期为document键使用整数值进行API POST。 唯一的区别似乎是我也在尝试使用此端点上传文件。

我觉得我缺少一些愚蠢的东西,但我不知道它是什么。

1 个答案:

答案 0 :(得分:0)

看来您不是用这种方式发送表单数据。 为了与文件一起发送数据,需要将它们分开:

response = requests.request(
    'POST',
    'http://127.0.0.1/api/dataset/visual',
    data={
        'name': 'Hello World',
        'description': 'from API',
        'document': 5,
    },
    files={
        'visual': ('hello_world.html', open('HELLOWORLD.html', 'rb')),
    }
)