Итак, я расширил модель User, чтобы добавить некоторые поля, и у меня возникли проблемы с частью POST изображения (аватара). Сначала есть страница профиля, отображающая информацию пользователя, а также ссылку для редактирования последнего. Как только на странице «editprofile» форма загружается и предварительно заполняется существующими данными. Когда файл аватара загружается, все работает нормально. Но когда нет аватара не загружается (независимо от того, уже есть одно или не профиль_пользователь), метод is_valid() не так:Django 1.7 request.FILES 'None' не подтвержден (is_valid())
Request Method: POST
Django Version: 1.7.4
Exception Type: TypeError
Exception Value: invalid file: None
Exception location: /usr/local/lib/python3.4/dist-packages/django/core/files/images.py in get_image_dimensions, line 46
Мой вопрос: как я могу пройти проверку с пустым полем (значение None) в request.FILES?
Вот мой код.
models.py
from django.db import models
from django.contrib.auth.models import User
from famsite import settings
from sorl.thumbnail import ImageField
class UserProfile(models.Model):
user = models.OneToOneField(User, primary_key=True)
birth_date = models.DateField('Date of birth', null=True)
phone1 = models.CharField('Primary phone', null=True, blank=True, max_length=15)
phone2 = models.CharField('Secondary phone', null=True, blank=True, max_length=15)
address = models.CharField('Address', null=True, blank=True, max_length=256)
avatar = ImageField('Avatar', upload_to='usrprofile/', blank=True)
forms.py
from django import forms
from django.core.files.images import get_image_dimensions
from django.utils.translation import ugettext as u_
from django.forms.extras.widgets import SelectDateWidget
import datetime
from usrprofile.models import UserProfile
class UserProfileForm(forms.ModelForm):
class Meta:
model = UserProfile
exclude = ['user']
fields = ['birth_date', 'phone1', 'phone2', 'email', 'address', 'avatar']
birth_date = forms.DateField(widget=SelectDateWidget(years=[y for y in range(1950, datetime.date.today().year)]))
email = forms.EmailField()
def clean_avatar(self):
avatar = self.cleaned_data['avatar']
try:
w, h = get_image_dimensions(avatar)
#validate dimensions
max_width = max_height = 100
if w > max_width or h > max_height:
raise forms.ValidationError(
u_('Please use an image that is '
'%s x %s pixels or smaller.') % (max_width, max_height))
#validate content type
main, sub = avatar.content_type.split('/')
if not (main == 'image' and sub in ['jpeg', 'pjpeg', 'gif', 'png']):
raise forms.ValidationError(u_('Please use a JPEG, '
'GIF or PNG image.'))
#validate file size
if len(avatar) > (20 * 1024):
raise forms.ValidationError(
u_('Avatar file size may not exceed 20k.'))
except AttributeError:
"""
Handles case when we are updating the user profile
and do not supply a new avatar
"""
pass
return avatar
views.py
from django.shortcuts import get_object_or_404, render, render_to_response
from django.http import HttpResponseRedirect, HttpResponseForbidden, HttpResponse
from django.core.urlresolvers import reverse
from django.views import generic
from django import forms
from django.template import RequestContext
from sorl.thumbnail import get_thumbnail
from usrprofile.models import UserProfile
from usrprofile.forms import *
class IndexView(generic.ListView):
model = UserProfile
template_name = 'usrprofile/profile.html'
def edit(request):
user = request.user
if request.method == 'POST':
#deletes old file in case of new file upload
form_aux = UserProfileForm(request.POST, request.FILES)
if form_aux.is_valid() and 'avatar' in request.FILES:
user.userprofile.avatar.delete()
#check if form has changed
#if form has changed, check if form is valid
#if form is valid, save data, associate with userprofile, save data to server
form = UserProfileForm(request.POST, request.FILES)
if form.has_changed():
if form.is_valid():
profile = form.save(commit=False)
profile.user = user
profile.save()
return render_to_response('usrprofile/profile.html', RequestContext(request))
else:
#if GET method, populate form with existing data
profile = user.userprofile
form = UserProfileForm(instance=profile, initial={'email': user.email})
return render_to_response('usrprofile/editprofile.html', RequestContext(request, {'form' : form}))
editprofile.html
{% extends "base.html" %}
{% load i18n %}
<html>
<head>
<title>{% block title %}{% trans "Profile edition" %}{% endblock %}</title>
</head>
<body>
<div id="content">
{% block content %}
<form id="form" method="POST" action="" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" name="submit" value="Save" />
</form>
{% endblock %}
</div>
</body>
</html>
Thnx, я пробовал, но все же ошибка. Я редактировал код. – mrj
Вы перенесете свою базу данных после этого изменения? – Selcuk
Juste did (не делал этого), все еще не работает :( – mrj