有没有办法在添加/编辑UserProfile模型的表单下显示用户字段?我正在扩展默认的Django用户模型:
class UserProfile(models.Model):
user = models.OneToOneField(User, unique=True)
about = models.TextField(blank=True)
我知道可以制作一个:
class UserProfileInlineAdmin(admin.TabularInline):
然后在User ModelAdmin中内联这个,但是我希望实现相反的效果,比如反向内联,在定义关系的模型页面中显示由OneToOne Relationship(User)指向的模型的字段(UserProfile) 。我不在乎它是在管理员中还是在自定义视图/模板中。我只需要知道如何实现这一目标。
我一直在努力使用ModelForms和Formsets,我知道答案就在那里,但我在Django的经验并不允许我提出解决方案。一个小例子真有帮助!
答案 0 :(得分:2)
之前提到过。
这是一篇博客文章,我认为这是我最喜欢的解决方案。要点是使用两个ModelForms,并使用<form>
kwarg将它们渲染到模板中的单个prefix
标记中:
http://collingrady.wordpress.com/2008/02/18/editing-multiple-objects-in-django-with-newforms/
这是我喜欢的另一种方法,但也有效。他们在页面上使用两个单独的<form>
,具有不同的操作和两个提交按钮:
Proper way to handle multiple forms on one page in Django
这个更具体地谈论用户和用户档案:
How to create a UserProfile form in Django with first_name, last_name modifications?
<强>更新强>
这是我最终的结果
# models.py
class UserProfile(models.Model):
favorite_color = models.CharField(max_length=30)
user = models.OneToOneField(User)
# forms.py
class UserProfileForm(forms.ModelForm):
class Meta:
model = UserProfile
# we fill the 'user' value in UserCreateView.form_valid
exclude = ('user',)
# views.py
from django.contrib.auth.forms import UserCreationForm
class UserCreateView(FormView):
# url to redirect to after successful form submission
success_url = reverse_lazy('user_list')
template_name = "userform.html"
def get_context_data(self, *args, **kwargs):
data = super(UserCreateView, self).get_context_data(*args, **kwargs)
data['userform'] = self.get_form(UserCreationForm, 'user')
data['userprofileform'] = self.get_form(UserProfileForm, 'userprofile')
return data
def post(self, request, *args, **kwargs):
forms = dict((
('userform', self.get_form(UserCreationForm, 'user')),
('userprofileform', self.get_form(UserProfileForm, 'userprofile')),
))
if all([f.is_valid() for f in forms.values()]):
return self.form_valid(forms)
else:
return self.form_invalid(forms)
def get_form(self, form_class, prefix):
return form_class(**self.get_form_kwargs(prefix))
def get_form_kwargs(self, prefix):
kwargs = super(UserCreateView, self).get_form_kwargs()
kwargs.update({'prefix': prefix})
return kwargs
def form_valid(self, forms):
user = forms['userform'].save()
userprofile = forms['userprofileform'].save(commit=False)
userprofile.user_id = user.id
userprofile.save()
return HttpResponseRedirect(self.get_success_url())
def get(self, request, *args, **kwargs):
return self.render_to_response(self.get_context_data())
# userform.html
<form action="" method="POST" class="form">
{% csrf_token %}
{{ userform.as_p }}
{{ userprofileform.as_p }}
<button type="submit">Submit</button>
</form>
# urls.py
...
url(r'^create/$', UserCreateView.as_view(), name='user_create'),
...