1

UserProfile モデルを追加/編集するフォームの下にユーザー フィールドを表示する方法はありますか? 次のように、デフォルトの Django User モデルを拡張しています。

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 での経験が少ないため、まだ解決策を思いつくことができません。少しの例は本当に役に立ちます!

4

1 に答える 1

2

これは以前にも取り上げました。

これは、私のお気に入りのソリューションだと思うブログ投稿です。要点は、2 つの ModelForms を使用し、 kwargを使用してテンプレート内の単一の<form>タグにレンダリングすることです。prefix

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

これは、私が少し好きではありませんが有効な別の方法です。ページ上で2 つの別々<form>の を使用し、異なるアクションと 2 つの送信ボタンを使用します。

Django で 1 つのページで複数のフォームを処理する適切な方法

これは、Users と UserProfiles についてより具体的に説明しています。

first_name、last_name を変更して Django で 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 に答える