python请求POST一个多部分编码的文件

时间:2016-02-29 22:59:34

标签: python django post file-upload python-requests

我正在努力学习django,这让我在绳子尽头。我正在使用请求尝试将用户上传的图像文件发布到外部网站following this example。出于测试目的,我使用请求bin作为网址,以便查看发布的内容。

当我将文件路径和名称硬编码到要测试的文件中时,整个过程非常有用。我的问题是我不知道如何处理现实世界的用例,我不知道用户对文件的命名,并且路径将根据日期而改变/月/年。

我在此看到的每篇帖子以及请求示例都是这样的:

>>> files = {'file': open('report.xls', 'rb')}

models.py

def get_image_path(instance, filename):
    return '/'.join(['help_screens/%Y/%m/%d', filename])

class Help(Timestamp):
First_name = models.CharField(max_length=30)
Last_name = models.CharField(max_length=40)
email = models.EmailField()
themessage = models.TextField()
screenshot = models.ImageField(
    upload_to=get_image_path,
    null=True,
    blank=True
)

views.py

def help_form(request):
    form = HelpForm()

    if request.method == 'POST':
        form = HelpForm( request.POST, request.FILES )

        if form.is_valid():
            First_name = form.cleaned_data['First_name']
            Last_name = form.cleaned_data['Last_name']
            email = form.cleaned_data['email']
            themessage = form.cleaned_data['themessage']
            screenshot = form.cleaned_data['screenshot']

            # Email the help request
            template = get_template('help_template.txt')

            context = Context({
                 'First_name': First_name,
                 'Last_name': Last_name,
                 'email': email,
                 'themessage': themessage,
                 'screenshot': screenshot,
             })
             content = template.render(context)

             mail = EmailMessage(
                 'New help request',
                 content,
                 'test website <test@test.com>',
                 ['my.test@mytest.com', email],
                 headers = {'Reply-To': email }
            )
            if screenshot:
                mail.attach(screenshot.name, screenshot.read())
            mail.send()
            # End email the help request

            form = form.save(commit=False)

            url = 'http://requestb.in/xxxxxx'
            payload = {
                'First_name': First_name,
                'Last_name': Last_name,
                'email': email,
                'themessage': themessage,
            }
            if screenshot != None:
            # this works, but it's a test to a hard-coded file. the           
            # problem remains, how to get the filepath and file.
            # files = {'screenshot': open('test/media-root/help_screens/boots.jpg', 'rb')}
            files = {'screenshot': open('screenshot.jpg', 'rb')}
            req = requests.post(url, data=payload, files=files)
        else:
            req = requests.post(url, data=payload)
            req.text
            form.save()

            return render(request, 'help/thanks.html')

    return render(request, 'help/help.html', {
        'form': form,
    })

1 个答案:

答案 0 :(得分:0)

例如,假设您的MEDIA_ROOT设置为&#39; / home / media&#39;并且upload_to设置为&#39; photos /%Y /%m /%d&#39;。 &#39;%Y /%m /%d&#39; upload_to的一部分是strftime()格式; &#39;%Y&#39;是四位数的年份,&#39;%m&#39;是两位数的月份和&#39;%d&#39;是两位数的日子。如果您在2007年1月15日上传文件,它将保存在目录/ home / media / photos / 2007/01/15中。

如果要检索上传文件的磁盘文件名或文件大小,可以分别使用名称和大小属性;有关可用属性和方法的更多信息,请参阅File类参考和管理文件主题指南。

来源:https://docs.djangoproject.com/en/1.9/ref/models/fields/#django.db.models.FileField.storage

以下是一些例子:https://docs.djangoproject.com/en/1.9/topics/files/

因此,要获得screenshot的名称,您必须screenshot.namescreenshot.path分别获取完整路径。