我很早就开始了我的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而不是?
答案 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'