title: Amazon S3 - Storing image files from Django - Don't upstream uploaded images by the user
body: <p>I have the custom <code>User</code> model in which I've add a <code>avatar</code> field</p>
  
  <pre><code>class User(AbstractBaseUser, PermissionsMixin):
  
      # email
      # username
      # first_name
      # last_name   
  
      avatar = models.ImageField(
          upload_to='avatars',
          blank=True,
          null=True,
          verbose_name='Photo'
      )
  </code></pre>
  
  <p>I've installed the following packages via <code>pip install</code>:</p>
  
  <pre><code>boto3==1.4.4
  django-boto==0.3.11
  django-storages==1.5.2
  django-storages-redux==1.3.2
  Pillow==4.0.0
  </code></pre>
  
  <p>I am using the following Amazon S3 configurations in my <code>settings.py</code></p>
  
  <pre><code>    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'
  </code></pre>
  
  <p>I have the <code>custom_storages.py</code> where I have some classes to store my static and media files. These clasess are subclassing by <code>S3BotoStorage</code></p>
  
  <pre><code>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
  </code></pre>
  
  <p>When I run <code>python manage.py collectstatic</code> my static files are stored in my amazon cloud S3 bucket in the assets directory according to my configuration and that's O.K.</p>
  
  <p>The issue comes when the images are uploaded by the users of my application. More precisely when an user upload their avatar profile.</p>
  
  <p>When an user upload the avatar profile via django admin, all it's works, such as follow:</p>
  
  <p><a href="https://i.stack.imgur.com/r6eww.gif" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/r6eww.gif" alt="enter image description here"></a></p>
  
  <p>And the image is stored in my amazon s3 bucket in the <code>media/avatars</code> directory.</p>
  
  <p><a href="https://i.stack.imgur.com/okDbc.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/okDbc.png" alt="enter image description here"></a></p>
  
  <p>But when an user try upload an image via Django frontend application via <code>forms.ModelForm</code> the image is not being upload, such as follow:</p>
  
  <p><a href="https://i.stack.imgur.com/LEtUb.gif" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/LEtUb.gif" alt="enter image description here"></a></p>
  
  <p>Why in my django admin the image is uploaded, but in my django application frontend via model form the image is not uploaded to S3?</p>
  
  <p>There is something which I am ignoring?</p>
  
  <p>I've these package third application named <a href="https://github.com/etianen/django-s3-storage" rel="nofollow noreferrer">django-s3-storage</a>, although I don't tested still </p>
  
  <p><strong>UPDATE</strong></p>
  
  <p>According to the comment/answer of <a href="https://stackoverflow.com/users/7645153/htn">@atn</a> my issue was in my html form in where I render the fields forms.</p>
  
  <p>My html template stay of this way:</p>
  
  <pre><code>{% extends 'layout.html' %}
  {% load bootstrap3 %}
  
  {% block title_tag %}Accounts | Settings | iHost {{ block.super }}{% endblock %}
  
  {% block body_content %}
  &lt;div class="container"&gt;
      &lt;h1&gt;Account Details&lt;/h1&gt;
      {% comment %} I've add enctype codification {% endcomment %}
  
      &lt;form enctype="multipart/form-data" method="POST"&gt;
          {% csrf_token %}
          {% bootstrap_form form %}
          &lt;input type="submit" value="Save Changes" class="btn btn-default"&gt;
      &lt;/form&gt;
  &lt;/div&gt;
  
  {% endblock %}
  </code></pre>
  
  <p>However I am intrigued by the second recommendations which <a href="https://stackoverflow.com/users/7645153/htn">@atn</a>
  give me:</p>
  
  <blockquote>
    <ol start="2">
    <li>Ensure "request.FILES" is included in save method(e.g. form = CustomForm(request.POST, request.FILES</li>
    </ol>
  </blockquote>
  
  <p>I understand that in some situations, is necessary check or evaluate the request we revceive. This may be in a form definition (forms.py) or in my views when I get the user request. This logic come from the <code>POST</code> nature.</p>
  
  <p>What happens to me is that sometimes I get confused when I should evaluate the request in a POST and from what location (form definition or my views)</p>
  
  <p>I know that my question is a newbie question, but I am interested in having some orientation about this.</p>
  
  <p>My forms.py and views.py for that situation are:</p>
  
  <p>My <code>forms.py</code>, in which I just customize some fields and nothing more. Is very basic really.</p>
  
  <pre><code>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()
  </code></pre>
  
  <p>And my views.py also is very basic. In her, I just call my model, my form and get the profile user data. </p>
  
  <pre><code>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
  </code></pre>
  
  <p>How can I add some validation type in my views or my forms in case is necessary. How to recognize it, how can I do?</p>
  
  <p>My apologies because is a newbie question.</p>