我可能会完全放弃这里的预订。 (请随时告诉我我是否是。)

我的用例是我有学校清单。学校模型非常简单:

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']

现在我有了我的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是用户学校的一个实例。

我关闭但缺少什么吗?我完全走错了道路吗?是否有更好的模型(例如,与“主人”的特殊用户一起使用一个学校实例)?

(还有一个小的复杂性 - 由于我是Django的老手,但是新的基于班级的视图,我试图使用香草视图,因为我发现更容易弄清楚发生了什么。)

有帮助吗?

解决方案

只是为了排除显而易见的事情 - 您不会将任何内容传递给表单构造函数。你尝试过吗 instance=user_school?可能还有更多需要工作,但我会从那里开始。

要对此进行一些扩展 - 在您看来,您完全覆盖了内置的内置 get 方法。很好,但这意味着您绕过了视图超类的自动化行为。具体来说, get 的方法 ProcessFormView (您的祖先课程之一)使用 get_form 视图类的方法。 FormMixin, ,另一个祖先定义 get_form:

return form_class(**self.get_form_kwargs())

get_form_kwargsModelFormMixin 添加 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