【问题标题】:Django forms: Update a user's attributes without changing usernameDjango 表单:在不更改用户名的情况下更新用户的属性
【发布时间】:2020-12-03 20:23:21
【问题描述】:

我正在尝试创建一个允许用户更新其用户名或头像的表单。我遇到的问题是,如果我在不更改用户名的情况下更新个人资料图片,django 表单验证if form.is_valid() 会将表单识别为无效,因为用户名已经存在于数据库中。我正在使用更新视图,但我不确定我是否正确实现了它。

当我尝试在不更改用户名的情况下更新头像时,我从以下行中看到“表单无效”的页面:HttpResponse("Form is invalid")。是否有解决方法来删除表单验证?我尝试删除 if form.is_valid():,但收到错误'User_form' object has no attribute 'cleaned_data'

我觉得必须有一种我无法找到的简单方法来解决这个问题,因为很多网站一次只允许您更新一个属性。

Views.py

    model = User
    form = User_form
    fields = ['username', 'avatar']
    template_name_suffix = '_update_form'

def update_profile(request, user_id): 
    if request.method == "POST":
        form = User_form(request.POST, request.FILES)
        if form.is_valid():
            user = User.objects.get(pk=user_id)
            username = form.cleaned_data['username']
            avatar = form.cleaned_data['avatar']
            if username != user.username:
                user.username = username
            if avatar != user.avatar: 
                if avatar:
                    user.avatar = avatar
            user.save()
            return redirect('index')
        else:
            return HttpResponse("Form is invalid")

models.py

class User(AbstractUser):
    followed_by = models.ManyToManyField("User", blank=True, related_name="following")
    avatar = models.ImageField(upload_to='profilepics/', verbose_name='Avatar', null=True, blank=True)

class User_form(ModelForm):
    class Meta: 
        model = User
        fields = ['username', 'avatar']

user_update_form.html

<form action="/profile/{{user.id}}/update" method="post" enctype='multipart/form-data'>
    {% csrf_token %}
    {{ form.as_p }}
    <input type="submit" value="Update">
</form>

【问题讨论】:

    标签: django forms authentication


    【解决方案1】:

    你自己做的工作太多了。 Django 的ModelForms 不仅可以创建数据,还可以更新数据。您通过instance=… 参数传递实例:

    from django.shortcuts import get_object_or_404
    
    def update_profile(request, user_id): 
        user = get_object_or_404(User, pk=user_id)
        if request.method == 'POST':
            form = User_form(request.POST, request.FILES, instance=user)
            if form.is_valid():
                form.save()
                return redirect('index')
            else:
                return HttpResponse('Form is invalid')
        else:
            form = User_form(instance=user)
        return render(request, 'some_template.html', {'form': form})

    对于唯一性检查,它会在检查用户名是否已经存在时排除实例。所以可以更改用户名,因为新用户名当然还不存在。

    【讨论】:

    • 啊,这完全成功了!正是我想要的。非常感谢。
    • 我遇到了第二个问题,那就是试图让密码字段显示为密码输入。无论我在那里尝试什么,它都不起作用,所以我决定完全摆脱 updateview 并将其作为模型形式传递。现在 instance=user 没有解决问题,因为表单不允许我输入空白用户名。我想我需要回到更新视图,但我该如何让更新视图显示密码输入而不仅仅是一个普通的字符输入字段?
    猜你喜欢
    • 2020-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-09
    • 1970-01-01
    • 2013-03-30
    • 2011-08-24
    • 2021-12-01
    相关资源
    最近更新 更多