如何在数据库中保存UserProfile图像(头像)的路径?

时间:2018-01-18 03:02:53

标签: python django django-models django-forms django-views

我无法确定在更新个人资料时如何存储用户上传的图片(他们的头像)。我在模型中使用的默认图像有效,但更新没有给出验证错误,但是当我提交时基本没有任何反应 - 默认图像保持不变。这是我的代码,非常感谢我对错误的理解。

user_profile / views.py

def update_user_profile(request, username):
    args = {}

    if request.method == 'POST':
        form = UpdateUserProfile(request.POST, request.FILES, instance=request.user)
        if request.user.username == username:
            if form.is_valid():
                form.save()
                return HttpResponseRedirect(reverse('user-profile', kwargs={'username': form.instance.username}))
        else:
            raise Http404()
    elif request.method == 'GET':
        if not request.user.username == username:
            raise Http404()
        else:
            form = UpdateUserProfile(instance=request.user)
    else:
        form = UpdateUserProfile(instance=request.user)

    args['form'] = form
    return render(request, 'storytime/update_user_profile.html', args)

user_profile / forms.py

class UpdateUserProfile(forms.ModelForm):
class Meta:
    model = UserProfile
    fields = ('first_name', 'last_name', 'email', 'avatar')


def clean_avatar(self):
    avatar = self.cleaned_data['avatar']

    try:
        width, height = get_image_dimensions(avatar)

        # validate dimensions
        max_width = max_height = 100
        if width > max_width or height > 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 and FileNotFoundError:
        """
        Handles case when we are updating the user profile
        and do not supply a new avatar
        """
        pass

    return avatar


def clean(self):
    cleaned_data = self.cleaned_data
    email = self.cleaned_data.get('email')
    first_name = self.cleaned_data.get('first_name')
    last_name = self.cleaned_data.get('last_name')

    # Checking if a username or email already exists, while excluding the
    # current user from that search
    if User.objects.filter(email=email).exclude(pk=self.instance.pk).exists():
        raise forms.ValidationError(('This email address is already in use.'),
        code='existing_username_or_email')

    return cleaned_data


def save(self, commit=True):
    user = super().save(commit=False)
    user.email = self.cleaned_data['email']
    user.first_name = self.cleaned_data.get('first_name')
    user.last_name = self.cleaned_data.get('last_name')
    user.avatar = self.clean_avatar()

    if commit:
        user.save()

    return user

user_profile / models.py

class UserProfile(models.Model):
    username = models.OneToOneField(
    User,
    on_delete='cascade',
    )
    first_name = models.CharField(
        verbose_name=('First Name'),
        max_length=32,
    )
    last_name = models.CharField(
        verbose_name=('Last Name'),
        max_length=32,
    )
    email = models.EmailField(
        verbose_name=('Email (You will login with this)'),
        max_length=32,
    )
    avatar = models.ImageField(
        upload_to='avatars',
        default='avatars/default-100.png',
        blank=True,
    )

    class Meta:
        verbose_name = ('user_profile')
        verbose_name_plural = ('user_profiles')

1 个答案:

答案 0 :(得分:0)

将它放在models.py文件中:

import os

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):
    new_filename = random.randint(1,3910209312) # this will generate new files' name
    name, ext = get_filename_ext(filename)
    final_filename = '{new_filename}{ext}'.format(new_filename=new_filename, ext=ext)
    return "images/{new_filename}/{final_filename}".format(
            new_filename=new_filename, 
            final_filename=final_filename
            )

在您的模型类中,相应地放置它:

image           = models.ImageField(upload_to=upload_image_path, null=True, blank=True)

我希望您的media设置已正确配置。

祝你好运。

最佳,

Dhaval。