1

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

私の使用例は、学校のリストを持っていることです。学校のモデルは非常に単純です。

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)

そこで、UserSchool の編集を処理するフォームを設定しました。

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

これで、EditSchool フォームができました。

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 は UserSchool のインスタンスです。

私は近くにいますが、何かが欠けていますか? 私は完全に間違った道を進んでいますか?これに適したモデルはありますか (「マスター」の特別なユーザーを持つ単一の School インスタンスを持つなど)?

(そして 1 つの小さな複雑な問題 - 私は Django の古い手ですが、クラスベースのビューは新しいので、何が起こっているのかを把握しやすいので、Vanilla Views を使用しようとしています。)

4

1 に答える 1

0

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

これを少し拡張すると、あなたの見解では、組み込みgetメソッドを完全にオーバーライドしています。それは問題ありませんが、ビュー スーパークラスの自動化された動作の一部をバイパスしていることを意味します。具体的には、get(ProcessFormView祖先クラスの 1 つ) のget_formメソッドは、ビュー クラスのメソッドを使用してフォームをインスタンス化します。FormMixin別の祖先である は、次のように定義しますget_form

return form_class(**self.get_form_kwargs())

そして、フォームのget_form_kwargsModelFormMixin追加します:self.objectkwargs

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、必要に応じてフォームにバインドします。

于 2013-11-08T02:41:34.223 に答える