質問

私はここで完全に予約から外れているかもしれません。 (私がいるかどうか教えてください。)

私のユースケースは、私が学校のリストを持っていることです。学校モデルは非常に簡単です:

class School(models.Model):
    name = models.CharField(max_length=100)
    mascot = models.CharField(max_length=100, null=True, blank=True)

私のユーザーがこれらの学校のいずれかを編集したいとき、私はそれらがマスターコピーを編集することを望まない。代わりに、私は彼らが一緒に遊ぶことができる彼ら自身のコピーを彼らに与えたいです。彼らが彼らのコピーの編集が完了したら、彼らは彼らの変更を提出することができ、他の誰かがそれを承認します。だから私は学校のユーザーのコピーのための別のクラスを持っています:

class UserSchool(models.Model):
    name = models.CharField(max_length=100)
    mascot = models.CharField(max_length=100, null=True, blank=True)
    master_school = models.ForeignKey(School)
    user = models.ForeignKey(settings.AUTH_USER_MODEL)

そこで、ユーザースクールの編集を処理するフォームを設定しました。

class UserSchoolForm(forms.ModelForm):
    class Meta:
        model = UserSchool
        fields = ['name','mascot']

そして今、私は私の編集フォームを持っています:

class EditSchool(UpdateView):
    model = School
    success_url = reverse_lazy('list_schools')
    form_class = UserSchoolForm

    def get(self, request, *args, **kwargs):
        school = self.get_object()

        # make a copy of the school for this user
        user_school, created = UserSchool.objects.get_or_create(
            master_school=school, user=request.user,
            defaults={'name' : school.name, 'mascot' : school.mascot})

        self.object = user_school
        form = UserSchoolForm()
        context = self.get_context_data(form=form)
        return self.render_to_response(context)

get()がコピーを正しく作成していることは知っていますが、フォームが表示されると、「名前」または「デフォルト」フィールドにリストされている値はありません。私の疑いは、問題はcls.model = schoolですが、self.objectはユーザースクールのインスタンスであるという事実にあるということです。

私は近くにいますが、何かが足りませんか?私は完全に間違った道を歩んでいますか?これのためのより良いモデルはありますか(「マスター」の特別なユーザーと一緒に単一の学校インスタンスを持っているなど)?

(そして1つの小さな合併症 - 私はDjangoの古い手であるが、新しいクラスベースのビューであるので、何が起こっているのかを理解しやすいと思うので、バニラの景色を使用しようとしています。)

役に立ちましたか?

解決

明らかなことを排除するために - あなたはフォームコンストラクターに何も渡していません。一緒に試しましたか instance=user_school?それ以上の仕事が必要かもしれませんが、私はそこから始めます。

これを少し拡張するために - あなたの見解では、あなたはビルトインを完全に無効にしています get 方法。それは問題ありませんが、それはあなたがあなたのビュースーパークラスの自動化された動作の一部をバイパスしていることを意味します。具体的には、 get の方法 ProcessFormView (あなたの祖先クラスの1つ)を使用してフォームをインスタンス化します get_form ビュークラスの方法。 FormMixin, 、別の祖先が定義します get_form:

return form_class(**self.get_form_kwargs())

get_form_kwargs の上 ModelFormMixin 追加します self.object フォームに kwargs:

kwargs.update({'instance': self.object})

あなたがオーバーライドされたからです get メソッドは呼び出されません get_form, 、電話もありません get_form_kwargs したがって、フォームの初期バインディングを提供するパス全体を通過しません。

私は個人的にこれを変更しようとします get_object カスタムビューの方法と残りのままにしておく:

class EditSchool(UpdateView):
    model = School
    success_url = reverse_lazy('list_schools')
    form_class = UserSchoolForm

    def get_object(self, queryset=None):
        school = super(EditSchool, self).get_object(queryset=queryset)
        user_school, created = UserSchool.objects.get_or_create(
            master_school=school, user=self.request.user,
            defaults={'name' : school.name, 'mascot' : school.mascot})
        return user_school

より多くの変更が必要かもしれません - 私はこれをテストしていません - しかし両方 getset 使用方法 get_object, 、必要に応じてフォームにバインドします。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top