开发者

Excluding a form field, yet adding it back in with clean()

开发者 https://www.devze.com 2023-01-23 09:29 出处:网络
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 s

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)


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.)


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)
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号