python - Django在不同服务器上传FileField和ImageField

标签 python python-3.x django django-models django-views

我想创建一个系统,用户可以上传文档文件和图像(两者用于不同的任务)

我想将文件存储在我自己的 ftp 服务器中,将图像存储在 s3 存储桶中。

我正在使用django-storages

从未见过这样的 django 方法,其中 FileFieldImageField 可以上传到不同的服务器

例如,假设当用户上传文件时,文件会上传到我的 ftp 服务器

FTP_USER = 'testuser'#os.environ['FTP_USER']
FTP_PASS = 'testpassword'#os.environ['FTP_PASS']
FTP_PORT = '21'#os.environ['FTP_PORT']
DEFAULT_FILE_STORAGE = 'storages.backends.ftp.FTPStorage'
FTP_STORAGE_LOCATION = 'ftp://' + FTP_USER + ':' + FTP_PASS + '@192.168.0.200:' + FTP_PORT




# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.11/howto/static-files/

STATIC_URL = '/static/'

STATICFILES_DIRS = [
    os.path.join(BASE_DIR, "static_my_proj"),
]

STATIC_ROOT = os.path.join(BASE_DIR, "static_cdn", "static_root")


MEDIA_URL = 'ftp://192.168.0.200/'
MEDIA_ROOT = 'ftp://192.168.0.200/'#os.path.join(BASE_DIR, "static_cdn", "media_root")

但问题是图像现在也转到 ftp 服务器

因为这个

DEFAULT_FILE_STORAGE = 'storages.backends.ftp.FTPStorage'

是的,我知道我可以在上传的服务器根目录中创建不同的目录,如下所示

def get_filename_ext(filepath):
    base_name = os.path.basename(filepath)
    name, ext = os.path.splitext(base_name)
    return name, ext


def upload_image_path(instance, filename):
    # print(instance)
    #print(filename)
    new_filename = random.randint(1,3910209312)
    name, ext = get_filename_ext(filename)
    final_filename = '{new_filename}{ext}'.format(new_filename=new_filename, ext=ext)
    return "myapp/{new_filename}/{final_filename}".format(
            new_filename=new_filename, 
            final_filename=final_filename
            )

class Product(models.Model):
    title           = models.CharField(max_length=120)
    slug            = models.SlugField(blank=True, unique=True)
    document        = models.FileField(upload_to=upload_image_path, null=True, blank=True)

    def get_absolute_url(self):
        #return "/products/{slug}/".format(slug=self.slug)
        return reverse("detail", kwargs={"slug": self.slug})

    def __str__(self):
        return self.title

但这不是我想要的,我想要不同的服务器用于文件和图像上传

这可能吗?我的意思是只能有一个 MEDIA_ROOT 那么我如何写两个服务器地址,我说得通吗?

编辑1:

iain shelvington提到了一个很好的观点,就是为每个字段添加存储选项以实现自定义存储后端

像这样

from storages.backends.ftp import FTPStorage
fs = FTPStorage()

class FTPTest(models.Model):
    file = models.FileField(upload_to='srv/ftp/', storage=fs)

class Document(models.Model):
    docfile = models.FileField(upload_to='documents')

并在设置中

DEFAULT_FILE_STORAGE = 'storages.backends.ftp.FTPStorage'
FTP_STORAGE_LOCATION = 'ftp://user:password@localhost:21

但是用户上传的照片也会上传到该 ftp 服务器 由于tp

DEFAULT_FILE_STORAGE = 'storages.backends.ftp.FTPStorage'

关于 MEDIA_URLMEDIA_ROOT 它们只能是一个,对吗? 那么我怎样才能在那里放置两个不同的服务器地址呢?

感谢您阅读本文,我真的很感激。

最佳答案

您可以在 FTPStorage 类中将 base_url 设置为

from storages.backends.ftp import FTPStorage
from django.conf import settings

fs = FTPStorage(<b>base_url=settings.FTP_STORAGE_LOCATION</b>)


class FTPTest(models.Model):
    file = models.FileField(upload_to='srv/ftp/', storage=fs)


class Document(models.Model):
    docfile = models.FileField(upload_to='documents')

base_url 对于构建文件的“绝对 URL” 非常有用,因此您不需要MEDIA_URLMEDIA_ROOT “在本例中”


I want different servers for file and image uploads.

您可以通过指定FileField(或ImageField)的storage参数来实现它

but user uploaded photos also gets uploaded to that ftp server due to, DEFAULT_FILE_STORAGE settings.

这是你的选择。在您的情况下,默认存储类别应该是什么?您需要将媒体文件上传到S3吗?或者项目运行的本地存储?相应地设置值。

关于python - Django在不同服务器上传FileField和ImageField,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63477477/

相关文章:

python - 在 Django 身份验证期间分别验证用户名和密码

python - (n,) 对于 numpy 数组形状意味着什么?

python - MongoDB 条件(如果存在则求和,否则为零)

python-3.x - 从 AppleScript 应用程序运行 python 脚本

python - 配置不当 ('SQLite 3.8.3 or later is required (found %s).' % Database.sqlite_version)

python - Python/Django 中 PHP "ob"函数的等效函数

python - 公司代理背后的 pip - 解决方法?

python - Nose 忽略使用自定义装饰器的测试

python-3.x - 使用 os.system 函数时设置超时

python - 使用 CSS 选择器和 BeautifulSoup 获取属性值