存储来自Django的图像文件的amazons3没有上传美国上传的图片

2024-04-26 18:25:12 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个自定义的User模型,在这个模型中我添加了一个avatar字段

class User(AbstractBaseUser, PermissionsMixin):

    # email
    # username
    # first_name
    # last_name   

    avatar = models.ImageField(
        upload_to='avatars',
        blank=True,
        null=True,
        verbose_name='Photo'
    )

我通过pip install安装了以下软件包:

^{pr2}$

我在我的settings.py中使用了以下amazons3配置

    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',

        # Third party apps
        'storages',

]

STATIC_URL = '/assets/'
STATICFILES_DIRS = (
    os.path.join(BASE_DIR, "assets"),
)

#Amazon S3 Storage
AWS_STORAGE_BUCKET_NAME = get_env_variable('AWS_STORAGE_BUCKET_NAME')
AWS_ACCESS_KEY_ID = get_env_variable('AWS_ACCESS_KEY_ID')
AWS_SECRET_ACCESS_KEY =  get_env_variable('AWS_SECRET_ACCESS_KEY')

# Tell django-storages that when coming up with the URL for an item in S3 storage, keep # it simple - just use this domain plus the path. 
# (If this isn't set, things get complicated).
# This controls how the `static` template tag from `staticfiles` gets expanded, if you're using it. We also use it in the next setting.
AWS_S3_CUSTOM_DOMAIN = '%s.s3.amazonaws.com' % AWS_STORAGE_BUCKET_NAME

# For media files to S3
STATICFILES_LOCATION = 'assets'
STATICFILES_STORAGE = 'custom_storages.StaticStorage'
STATIC_URL = "https://%s/%s/" % (AWS_S3_CUSTOM_DOMAIN, STATICFILES_LOCATION)
MEDIAFILES_LOCATION = 'media'
MEDIA_URL = "https://%s/%s/" % (AWS_S3_CUSTOM_DOMAIN, MEDIAFILES_LOCATION)
DEFAULT_FILE_STORAGE = 'custom_storages.MediaStorage'

我在custom_storages.py中有一些类来存储我的静态和媒体文件。这些类由S3BotoStorage子类化

from django.conf import settings
from storages.backends.s3boto import S3BotoStorage

# custom_storages.py 
class StaticStorage(S3BotoStorage):
    location = settings.STATICFILES_LOCATION

class MediaStorage(S3BotoStorage):
    location = settings.MEDIAFILES_LOCATION

当我运行python manage.py collectstatic时,我的静态文件根据我的配置存储在assets目录中的amazon cloud S3存储桶中,这没问题

当我的应用程序的用户上传图片时,问题就来了。更准确地说,当用户上传他们的头像档案。在

当用户通过django admin上传avatar配置文件时,它的所有功能都会起作用,例如:

enter image description here

图像存储在我的amazons3存储桶中的media/avatars目录中。在

enter image description here

但是当用户尝试通过Django前端应用程序通过forms.ModelForm上传图像时,图像不会被上传,例如:

enter image description here

为什么在我的django管理中图像被上传,但是在我的django应用程序前端通过模型表单没有上传到S3?在

有什么事我忽略了?在

我已经将第三个应用程序包命名为django-s3-storage,尽管我还没有测试

更新

根据@atn的评论/答案,我的问题是在我呈现字段表单的html表单中。在

我的html模板保持不变:

{% extends 'layout.html' %}
{% load bootstrap3 %}

{% block title_tag %}Accounts | Settings | iHost {{ block.super }}{% endblock %}

{% block body_content %}
<div class="container">
    <h1>Account Details</h1>
    {% comment %} I've add enctype codification {% endcomment %}

    <form enctype="multipart/form-data" method="POST">
        {% csrf_token %}
        {% bootstrap_form form %}
        <input type="submit" value="Save Changes" class="btn btn-default">
    </form>
</div>

{% endblock %}

不过,我对第二个建议很感兴趣@atn 给我:

  1. Ensure "request.FILES" is included in save method(e.g. form = CustomForm(request.POST, request.FILES

我知道在某些情况下,有必要检查或评估我们收到的请求。这可能是一个表单定义(表单.py)或者当我收到用户请求时。这个逻辑来自POST的本质。在

发生在我身上的情况是,有时我会搞不清什么时候应该在帖子中评估请求,以及从什么位置(表单定义或我的视图)评估请求

我知道我的问题是一个新手问题,但我有兴趣有一些关于这个问题的方向。在

我的表单.py以及视图.py对于这种情况:

我的forms.py,其中我只自定义了一些字段,没有其他内容。真的很基本。在

class UserUpdateForm(forms.ModelForm):
    speak_languages = forms.MultipleChoiceField(
        required=False,
        label='Speak languages',
        widget=CheckboxSelectMultiple(),
        choices=User.LANGUAGES_CHOICES,
    )
    bio = forms.CharField(widget=forms.Textarea)

    class Meta:
        widgets = {
            'gender':forms.RadioSelect,
            'country_of_origin': CountrySelectWidget(),
            'country_current_residence': CountrySelectWidget(),
            'date_of_birth': DateInput(), #datepicker
        }
        fields = ("first_name", "last_name", "display_name", "gender",
        "country_of_origin", "city_of_origin", "country_current_residence",
        "city_current_residence", "speak_languages", "phone_number",
        "address", "bio", "avatar", "date_of_birth", "is_student",
        "is_professor", "is_executive", "is_study_host",
        "is_hosting_host", "is_innovation_host", "is_entertainment_host",
        "is_other_services_host", "entertainment_activities",)

        model = get_user_model()

还有我的视图.py也是很基本的。在她身上,我只需要调用我的模型,我的表单,然后得到配置文件用户数据。在

class AccountSettingsUpdateView(LoginRequiredMixin, UpdateView):
    model = get_user_model()
    form_class = UserUpdateForm
    success_url = reverse_lazy('dashboard')
    context_object_name = 'preferences'

    def get_context_data(self, **kwargs):
        context = super(AccountSettingsUpdateView, self).get_context_data(**kwargs)

        user = self.request.user
        if user.is_student:
            profile = user.get_student_profile()
            context['userprofile'] = profile
        elif user.is_professor:
            profile = user.get_professor_profile()
            context['userprofile'] = profile
        elif user.is_executive:
            profile = user.get_executive_profile()
            context['userprofile'] = profile
        elif user.is_study_host:
            profile = user.get_study_host_profile()
            context['userprofile'] = profile
        elif user.is_hosting_host:
            profile = user.get_hosting_host_profile()
            context['userprofile'] = profile
        elif user.is_active:
            #profile = user.get_user_profile()
            context['userprofile'] = self.request.user
        return context

如何在视图或表单中添加一些验证类型以备需要。如何识别,我该怎么做?在

我很抱歉,因为这是一个新手问题。在


Tags: djangonamepyawshost表单gets3