Django用户更新表单和视图

时间:2016-05-26 07:06:09

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

我很早就开始了我的Django / Python开发之旅,在经过几个小时/几天的头部刮擦和反复试验之后,我已经能够慢慢弄清楚了。我现在有一个常见问题,即我无法正常工作:

如何创建用户个人资料更新视图/表单?

我已经破解了Stack Overflow的几个解决方案,到目前为止我无法弄清楚我做错了什么。这是我使用Django 1.9的不良尝试的初始版本:

#forms.py
class profileForm(forms.ModelForm):
    class Meta:
        model = User
        fields = ['first_name', 'last_name', 'email']

#views.py
@login_required
def profile(request):
    if request.method == 'POST':
        form = profileForm(data=request.POST, instance=request.user)
        update = form.save(commit=False)
        update.user = request.user
        update.save()
    else:
        form = profileForm(instance=request.user)

    return render(request, 'profile.html', {'form': form})

#urls.py
urlpatterns = [
    url(r'^dashboard/$', views.dashboard, name='dashboard'),
    url(r'^dashboard/profile$', views.profile, name='profile'),
]

#profile.html
<form action="." method="post">
    {% csrf_token %}
    {{ form.as_p }}
    <button type="submit">Update Profile</button>
</form>

因此,我的更新用户配置文件视图的当前行为是不更新POST中表单中的任何指定字段,但页面会加载到其他URL。例如,个人资料更新表单的网址是 / dashboard / profile ,它会在表单提交时重定向到 / dashboard 。如果我在Django管理员中手动添加email / first_name / last_name,它会在我的表单中正确显示...我只是无法保存更新的数据。

我确实有上面代码的版本也给了我用户名错误,我猜这可能是接近解决方案的?最后我想使用电子邮件地址作为用户名,但是一旦我有一个超简单的工作资料更新表格,我想自己想出来。

我提前为这个愚蠢的问题道歉,我已经谷歌搜索并尝试了其他解决方案,但我要么无法得到相同的初始错误,要么无法获得详细的工作版本。

谢谢大家,祝你有一个美好的一天/晚上!

修改

我也尝试了这个解决方案How to update User object without creating new one?,它也有相同的行为:不更新POST中表单中的任何指定字段,但页面确实加载到不同的URL ...这让我很困惑更多,也许问题出在我的urls.py而不是?

2 个答案:

答案 0 :(得分:1)

这里的用户没有什么特别的。你有两个问题:第一个是因为你的网址。您的个人资料视图不以斜杠结尾,因此表单的操作为“。”将它发送给父项“/ dashboard”,它根本不会通过处理代码。

url(r'/dashboard/profile/$'...)

其次,模型不会更新,因为您没有调用表单的valdation方法。

if request.method == 'POST':
    form = profileForm(data=request.POST, instance=request.user)
    if form.is_valid():
        form.save()
        return redirect('somewhere')

注意没有理由在这里使用commit = False;该实例已经是用户。

答案 1 :(得分:0)

我尝试使用抽象用户,它运行良好。首先,我创建了一个名为仪表板的应用程序。然后覆盖默认的用户模型。

现在更新仪表板应用程序-models.py,urls.py,forms.py和views.py

在models.py

class User(AbstractUser):    
    middle_name = models.CharField(max_length=50, blank=True, null=True)
    sdl_service_code = models.CharField(choices=SDL_CHOICES, max_length=5)
    account = models.CharField(choices=ACCOUNT_CHOICES, max_length=5)

我通过更新如下设置文件,使这个新的用户模型(在仪表板应用中)成为django默认用户模型

在settings.py

AUTH_USER_MODEL = 'dashboard.User'

在urls.py

urlpatterns = [
    path('users', ListUserView.as_view(), name='users'),
    path('users/add/', CreateUserView.as_view(), name='users-add'),
    path('users/<int:pk>/', UpdateUserView.as_view(), name='users-edit'),
    )
]

在forms.py

class UserForm(forms.ModelForm):            
        middle_name = forms.CharField(required=False, max_length=50)
        password = forms.CharField(widget=forms.PasswordInput())
        about_company = form.CharField(required=False, max_length=50)

        def __init__(self, *args, **kwargs):
            super(UserForm, self).__init__(*args, **kwargs)
            for field in iter(self.fields):
                self.fields[field].widget.attrs.update({
                    'class': 'form-control',
                    'placeholder': '{}'.format(field).replace("_", ' ').capitalize(),

                })

            self.fields['email'].widget.attrs['placeholder'] = 'abc@xyz.com'
            self.fields['email'].required = True
            self.fields['first_name'].required = True
            self.fields['last_name'].required = True
            self.fields['password'].required = True

            if self.instance.pk:
                self.fields['username'].required = False
                self.fields['username'].widget.attrs['readonly'] = True
                self.fields['email'].required = False
                self.fields['email'].widget.attrs['readonly'] = True
                self.fields['password'].widget.attrs['readonly'] = True
                self.fields['password'].required = False

        def save(self, *args, **kwargs):
            self.date_joined = date.today()
            super(UserForm, self).save(*args, **kwargs)
            return self

        class Meta:
            model = User
            fields = '__all__'
            exclude = ('date_joined',)

在views.py

from dashboard.models import User
from django.views.generic import ListView, DetailView, CreateView, UpdateView
from dashboard.forms import UserForm

class CreateUserView(CreateView):
    model = User
    template_name = 'dashboard/user_add.html'
    form_class = UserForm

    def get_success_url(self):
        return '/users'

class UpdateUserView(UpdateView):
    model = User
    form_class = UserForm
    template_name = 'dashboard/user_add.html'
    success_url = '/users'

class ListUserView(ListView):
    model = User
    template_name = 'dashboard/user_list.html'