排除表单字段,但使用 clean() 将其添加回来

发布于 2024-09-30 04:23:10 字数 1099 浏览 4 评论 0原文

在 django 管理中,我有一个内联,我希望自动填写查看用户。在 clean 函数中,它用 request.user 填充 created_by 字段。问题在于,由于表单排除了created_by字段,因此插入cleaned_fields的值显然会被忽略。我该怎么做?我希望该小部件根本不显示。

class NoteInline(admin.TabularInline):
    model = Note
    extra = 1
    can_delete = False

    def get_formset(self, request, obj=None, **kwargs):
        """
        Generate a form with the viewing CSA filled in automatically
        """

        class NoteForm(forms.ModelForm):

            def clean(self):
                self.cleaned_data['created_by'] = request.user
                return self.cleaned_data

            class Meta:
                exclude = ('created_by', )
                model = Note
                widgets = {'note': forms.TextInput(attrs={'style': "width:80%"})}

        return forms.models.inlineformset_factory(UserProfile, Note,
                                                  extra=self.extra,
                                                  form=NoteForm,
                                                  can_delete=self.can_delete)

In the django admin, I have an inline that I want to have the viewing user filled in automatically. During the clean function, it fills in the created_by field with request.user. The problem is that since the created_by field is excluded by the form, the value that gets inserted into cleaned_fields gets ignored apparently. How can I do this? I want the widget t not be displayed at all.

class NoteInline(admin.TabularInline):
    model = Note
    extra = 1
    can_delete = False

    def get_formset(self, request, obj=None, **kwargs):
        """
        Generate a form with the viewing CSA filled in automatically
        """

        class NoteForm(forms.ModelForm):

            def clean(self):
                self.cleaned_data['created_by'] = request.user
                return self.cleaned_data

            class Meta:
                exclude = ('created_by', )
                model = Note
                widgets = {'note': forms.TextInput(attrs={'style': "width:80%"})}

        return forms.models.inlineformset_factory(UserProfile, Note,
                                                  extra=self.extra,
                                                  form=NoteForm,
                                                  can_delete=self.can_delete)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

捶死心动 2024-10-07 04:23:10

原始建议:

为什么不直接保留该字段,而不是排除它,然后将其设为隐藏输入?

class NoteForm(forms.ModelForm):

def __init__(*args, **kwargs):
   super(NoteForm, self).__init__(*args, **kwargs)

   self.fields['created_by'].widget = forms.widgets.HiddenInput()


#rest of your form code follows, except you don't exclude 'created_by' any more    

建议#2(因为隐藏字段仍然出现在内联的列标题中):

根本不要在 clean() 方法中设置 self.cleaned_data['created_by'] 。相反,重写 NoteForm.save() 并将其设置在那里。

(如果可以的话,可以将请求传递给 save(),或者通过将其添加到 self 来将其缓存在 init 中,或者像您已经做的那样将其用作类级变量。 )

ORIGINAL SUGGESTION:

Why not just leave the field in place, rather than excluding it and then make it a hiddeninput?

class NoteForm(forms.ModelForm):

def __init__(*args, **kwargs):
   super(NoteForm, self).__init__(*args, **kwargs)

   self.fields['created_by'].widget = forms.widgets.HiddenInput()


#rest of your form code follows, except you don't exclude 'created_by' any more    

SUGGESTION #2 (because the hidden field still appears in the column header in the inline):

Don't set self.cleaned_data['created_by'] in the clean() method at all. Instead, override NoteForm.save() and set it there.

(Either pass in the request to save(), if you can, or cache it in the init by adding it to self, or use it as a class-level variable as you appear to do already.)

九公里浅绿 2024-10-07 04:23:10

我的解决方案是编辑 Inline 的 formfield_for_foreignkey 函数,这将下拉列表限制为仅限登录用户。

class NoteInline(admin.TabularInline):
    model = Note
    extra = 1
    can_delete = False

    def queryset(self, request):
        return Note.objects.get_empty_query_set()

    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        if db_field.name == 'created_by':
            # limit the 'created_by' dropdown box to just the CSR user who is
            # logged in and viewing the page.
            kwargs['queryset'] = User.objects.filter(pk=request.user.pk)
        return super(NoteInline, self).formfield_for_foreignkey(db_field, request, **kwargs)

My solution was to edit the formfield_for_foreignkey function for the Inline, which restricted the dropdown to just the logged in user.

class NoteInline(admin.TabularInline):
    model = Note
    extra = 1
    can_delete = False

    def queryset(self, request):
        return Note.objects.get_empty_query_set()

    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        if db_field.name == 'created_by':
            # limit the 'created_by' dropdown box to just the CSR user who is
            # logged in and viewing the page.
            kwargs['queryset'] = User.objects.filter(pk=request.user.pk)
        return super(NoteInline, self).formfield_for_foreignkey(db_field, request, **kwargs)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文