0

I am a beginner with Django. I have a problem when I am filling the registration form. I can't upload any image. If the ImageField is set to required=true, it's never validated, impossible to submit. If required=false, it's possible to submit it but the image is never saved in destination folder (model). However, I can upload the image from the admin panel as a super user.

MODELS.PY

from __future__ import unicode_literals
from django.contrib.auth.models import AbstractUser, UserManager
from django.db import models
from django.utils import timezone

class AccountUserManager(UserManager):
    def _create_user(self, username, email, password,
                     is_staff, is_superuser, **extra_fields):

        now = timezone.now()
        if not email:
            raise ValueError('The given username must be set')

        email = self.normalize_email(email)
        user = self.model(username=email, email=email,
                          is_staff=is_staff, is_active=True,
                          is_superuser=is_superuser,
                          date_joined=now, **extra_fields)
        user.set_password(password)
        user.save(using=self._db)

        return user

class User(AbstractUser):

    """
    Here goes a little code for stripe, but I removed it for making it shorter.
    """
    team = models.CharField(max_length=20, default='')
    photo = models.ImageField('photo', upload_to='static/media/profiles/', null=True, blank=True)

    objects = AccountUserManager()

The views.py

VIEWS.PY

from django.contrib import messages, auth
from django.contrib.auth.decorators import login_required

from accounts.forms import UserRegistrationForm, UserLoginForm
from django.core.urlresolvers import reverse
from django.shortcuts import render, redirect, get_object_or_404
from django.template.context_processors import csrf
from django.conf import settings
import datetime
from django.views.decorators.csrf import csrf_exempt
from django.http import HttpResponse
from models import User
import stripe
import arrow
import json
from django.http import Http404, HttpResponseRedirect

from forms import UpdateProfileForm


stripe.api_key = settings.STRIPE_SECRET


def register(request):
    if request.method == 'POST':
        form = UserRegistrationForm(request.POST)
        if form.is_valid():
            try:
                customer = stripe.Customer.create(

                    email=form.cleaned_data['email'],
                    card=form.cleaned_data['stripe_id'],
                    plan='REG_MONTHLY',
                )
            except stripe.error.CardError, e:
                messages.error(request, "Your card was declined!")

            if customer:
                user = form.save()
                user.stripe_id = customer.id
                user.subscription_end = arrow.now().replace(weeks=+4).datetime
                user.save()

                user = auth.authenticate(email=request.POST.get('email'), password=request.POST.get('password1'))

                if user:
                    auth.login(request, user)
                    messages.success(request, "You have successfully registered")
                    return redirect(reverse('profile'))

                else:
                    messages.error(request, "We were unable to log you in at this time")
            else:
                messages.error(request, "We were unable to take payment from the card provided")
    else:
        today = datetime.date.today()
        form = UserRegistrationForm(initial={'expiry_month': today.month, 'expiry_year': today.year})

    args = {'form': form, 'publishable': settings.STRIPE_PUBLISHABLE}
    args.update(csrf(request))
    return render(request, 'register.html', args)
...

And here comes forms.py:

FORMS.PY

from django import forms
from django.contrib.auth.forms import UserCreationForm
from accounts.models import User
from django.core.exceptions import ValidationError


class UserRegistrationForm(UserCreationForm):
    """More fields for stripe"""
    photo = forms.ImageField(label='Photo', required=False)
    team = forms.CharField(label='team')

    password1 = forms.CharField(
        label='Password',
        widget=forms.PasswordInput
    )

    password2 = forms.CharField(
        label='Password confirmation',
        widget=forms.PasswordInput
    )

    class Meta:
        model = User
        fields = ['email', 'password1', 'password2', 'team', 'photo']
        exclude = ['username']

    def clean_password2(self):
        password1 = self.cleaned_data.get('password1')
        password2 = self.cleaned_data.get('password2')

        if password1 and password2 and password1 != password2:
            message = "Passwords do not match"
            raise forms.ValidationError(message)

        return password2

    def clean_email(self):
        email = self.cleaned_data.get('email')

        if not email:
            message = "Please enter your email address"
            raise forms.ValidationError(message)

        return email


    def save(self, commit=True):
        instance = super(UserRegistrationForm, self).save(commit=False)

        # automatically set to email address to create a unique identifier
        instance.username = instance.email

        if commit:
            instance.save()

        return instance
...

Maybe the image is not saved... I'm lost. I've been 3 days reading posts here, but I haven't found any solution. I saw a similar issue as mine, but with a different approach, but not resolved yet. Django: upload image to form

Thanks.

kk.
  • 3,747
  • 12
  • 36
  • 67
Dubliner
  • 91
  • 1
  • 2
  • 12
  • Hi Raja! Should I add in views.py, inside if validated...: if 'photo' in request.FILES: form.photo =request.FILES['photo'] form.save() – Dubliner Jul 24 '16 at 12:39
  • Thanks Raja, I've added this in views.py: if 'photo' in request.FILES: form.photo =request.FILES['photo'] between user=... and if user But it doesn't work. Maybe I have to put it in another place... – Dubliner Jul 24 '16 at 13:13
  • No. I didn't have it. Let me try. – Dubliner Jul 24 '16 at 13:21
  • I've added it and now, after submitting the form, every field appear as required. It seem's nothing validated. – Dubliner Jul 24 '16 at 13:24
  • @Raja Thanks for your help! It finally worked. As you told me, I added (1) if 'photo' in request.FILES: form.photo =request.FILES['photo'] (2) form = UserRegistrationForm(request.POST, request.FILES) (3) enctype="multipart/form-data" – Dubliner Jul 24 '16 at 13:47

2 Answers2

1

You have to add request.FILES in form class

form = UserRegistrationForm(request.POST)

And also form.photo = request.FILES['photo']

Raja Simon
  • 10,126
  • 5
  • 43
  • 74
1

i think maybe you forget to add enctype="multipart/form-data" to the form.

Bass
  • 11
  • 1