[英]Uploading on Django with Boto3
So I've been working on a Django site and I'm rather stuck. 所以我一直在Django网站上工作而且我很困难。 I can't seem to figure out how to properly use Boto3 to upload files to a Digital Ocean Space. 我似乎无法弄清楚如何正确使用Boto3将文件上传到数字海洋空间。 I have a python script that does what I want, but I can't figure out how to make it work with Django on a web page. 我有一个python脚本,可以做我想要的,但我无法弄清楚如何在网页上使用Django。 I've read through a lot of documentation but I can't seem to find a clear answer. 我已阅读了大量文档,但似乎无法找到明确的答案。 Also all the examples are using AWS. 所有示例都使用AWS。 Here is the code that I have so far: 这是我到目前为止的代码:
Python Upload Script: Python上传脚本:
from boto3 import session
from botocore.client import Config
ACCESS_ID = '-----'
SECRET_KEY = '-----'
# Initiate session
session = session.Session()
client = session.client('s3',
region_name='nyc3',
endpoint_url='https://nyc3.digitaloceanspaces.com',
aws_access_key_id=ACCESS_ID,
aws_secret_access_key=SECRET_KEY)
# Upload file to Space 'from folder/file','space to put','name it will become'
def run(upfile):
client.upload_file(upfile, 'yl2-test', 'test/storage-test')
views.py: views.py:
from django.shortcuts import render
from django.shortcuts import redirect
from django.contrib.auth import authenticate, login
from django.http import HttpResponseRedirect
from .forms import CharacterForm, SignUpForm
from scripts.test_upload import run
def index(request):
return render(request, 'YL2/index.html')
def new_char(request):
# return render(request, 'YL2/new_char.html')
# if this is a POST request we need to process the form data
if request.method == 'POST':
# create a form instance and populate it with data from the request:
form = CharacterForm(request.POST, request.FILES)
# check whether it's valid:
if form.is_valid():
# process the data in form.cleaned_data as required
run(request.FILES['char_file'])
run(request.FILES['char_image'])
# redirect to a (success page) new URL:
return HttpResponseRedirect('')
# if a GET (or any other method) we'll create a blank form
else:
form = CharacterForm()
return render(request, 'YL2/new_char.html', {'form': form})
def log_in_page(request):
username = request.POST['username']
password = request.POST['password']
user = authenticate(request, username=username, password=password)
if user is not None:
login(request, user)
return redirect('index')
else:
return HttpResponseRedirect('Login error. Try again.')
def SignUp(request):
if request.method == 'POST':
form = SignUpForm(request.POST)
if form.is_valid():
form.save()
username = form.cleaned_data.get('username')
raw_password = form.cleaned_data.get('password1')
user = authenticate(username=username, password=raw_password)
login(request, user)
return redirect('index')
else:
form = SignUpForm()
return render(request, 'signup.html', {'form': form})
models.py: models.py:
from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
from django.dispatch import receiver
class UserProfile(models.Model):
# -----
class Character(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
char_name = models.CharField(max_length=100)
char_image = models.ImageField()
char_file = models.FileField(max_length=100)
# upload_to='uploads/'
@receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
if created:
UserProfile.objects.create(user=instance)
@receiver(post_save, sender=User)
def save_user_profile(sender, instance, **kwargs):
instance.userprofile.save()
forms.py: forms.py:
from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
class CharacterForm(forms.Form):
char_name = forms.CharField(label='Character Name', max_length=100)
char_image = forms.ImageField(label='Character Image')
char_file = forms.FileField(label='Character File')
class SignUpForm(UserCreationForm):
email = forms.EmailField(max_length=254, help_text='Required. Input a valid email address.')
class Meta:
model = User
fields = ('username', 'email', 'password1', 'password2', )
new_char.html: new_char.html:
<h1>New Character for: {{ user.username }}</h1>
<form enctype="multipart/form-data" action="/new_char/" method="post">
{% csrf_token %}
{{ form.as_ul }}<br><br>
<input type="submit" value="Submit" />
</form>
Edit: 编辑:
Adding error with full trace info. 使用完整跟踪信息添加错误。
Error: 错误:
ValueError at /new_char/
Filename must be a string
Request Method: POST
Request URL: http://127.0.0.1:8000/new_char/
Django Version: 2.0.4
Exception Type: ValueError
Exception Value:
Filename must be a string
Exception Location: /usr/local/lib/python3.6/site-packages/boto3/s3/transfer.py in upload_file, line 273
Python Executable: /usr/local/opt/python/bin/python3.6
Python Version: 3.6.5
Python Path:
['/Users/---user---/code/---project---',
'/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python36.zip',
'/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6',
'/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/lib-dynload',
'/Users/---user---/Library/Python/3.6/lib/python/site-packages',
'/usr/local/lib/python3.6/site-packages']
Server time: Wed, 13 Jun 2018 11:00:26 -0600
Trace: 跟踪:
Environment:
Request Method: POST
Request URL: http://127.0.0.1:8000/new_char/
Django Version: 2.0.4
Python Version: 3.6.5
Installed Applications:
['YL2.apps.Yl2Config',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware']
Traceback:
File "/usr/local/lib/python3.6/site-packages/django/core/handlers/exception.py" in inner
35. response = get_response(request)
File "/usr/local/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response
128. response = self.process_exception_by_middleware(e, request)
File "/usr/local/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response
126. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Users/---user---/code/---project---/YL2/views.py" in new_char
24. run(request.FILES['char_file'])
File "/Users/---user---/code/---project---/scripts/test_upload.py" in run
20. client.upload_file(upfile, 'yl2-test', 'test/storage-test')
File "/usr/local/lib/python3.6/site-packages/boto3/s3/inject.py" in upload_file
131. extra_args=ExtraArgs, callback=Callback)
File "/usr/local/lib/python3.6/site-packages/boto3/s3/transfer.py" in upload_file
273. raise ValueError('Filename must be a string')
Exception Type: ValueError at /new_char/
Exception Value: Filename must be a string
The upload_file
method is for uploading a file stored on local disk and referenced via its filename, so it is expecting you to pass that filename as a string. upload_file
方法用于上传存储在本地磁盘上并通过其文件名引用的文件,因此期望您将该文件名作为字符串传递。
Instead, you should use upload_fileobj
, which uploads a file from an object - which is what you have. 相反,您应该使用upload_fileobj
,它从对象上传文件 - 这就是您所拥有的。
(Note, this has nothing to do with any differences between AWS and DigitalOcean.) (注意,这与AWS和DigitalOcean之间的任何差异无关。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.