1

有没有办法在添加/编辑 UserProfile 模型的表单下显示用户字段?我正在扩展默认的 Django 用户模型,如下所示:

class UserProfile(models.Model):
    user = models.OneToOneField(User, unique=True)
    about = models.TextField(blank=True)

我知道可以制作:

class UserProfileInlineAdmin(admin.TabularInline):

然后在 User ModelAdmin 中内联它,但我想达到相反的效果,比如反向内联,在定义关系的模型页面(UserProfile)中显示 OneToOne 关系(用户)指向的模型字段。我不在乎它是在管理员中还是在自定义视图/模板中。我只需要知道如何实现这一点。

我一直在为 ModelForms 和 Formsets 苦苦挣扎,我知道答案就在某个地方,但是我在 Django 中的一点经验还不能让我想出解决方案。一个小例子真的很有帮助!

4

1 回答 1

2

这个以前就提过。

这是一篇博客文章,其中包含我认为我最喜欢的解决方案。要点是使用两个 ModelForms,并利用 kwarg 将它们渲染到模板中的单个<form>标签中prefix

http://collingrady.wordpress.com/2008/02/18/editing-multiple-objects-in-django-with-newforms/

这是另一种我不太喜欢的方法,但也是有效的。他们在页面上使用了两个单独<form>的 s,具有不同的操作和两个提交按钮:

在 Django 中处理一页上的多个表单的正确方法

这一篇更具体地讨论了用户和用户配置文件:

如何在 Django 中使用 first_name、last_name 修改创建 UserProfile 表单?

更新

这是我最终得到的

# 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'),
...
于 2012-10-11T21:07:07.910 回答