django admin - add custom form fields that are not part of the model

后端 未结 5 1208
无人及你
无人及你 2020-11-30 18:07

I have a model registered in the admin site. One of its fields is a long string expression. I\'d like to add custom form fields to the add/update page of this model in the a

相关标签:
5条回答
  • 2020-11-30 18:43

    you can always create new admin template , and do what you need in your admin_view (override the admin add url to your admin_view):

     url(r'^admin/mymodel/mymodel/add/$' , 'admin_views.add_my_special_model')
    
    0 讨论(0)
  • 2020-11-30 18:50

    It it possible to do in the admin, but there is not a very straightforward way to it. Also, I would like to advice to keep most business logic in your models, so you won't be dependent on the Django Admin.

    Maybe it would be easier (and maybe even better) if you have the two seperate fields on your model. Then add a method on your model that combines them.

    For example:

    class MyModel(models.model):
    
        field1 = models.CharField(max_length=10)
        field2 = models.CharField(max_length=10)
    
        def combined_fields(self):
            return '{} {}'.format(self.field1, self.field2)
    

    Then in the admin you can add the combined_fields() as a readonly field:

    class MyModelAdmin(models.ModelAdmin):
    
        list_display = ('field1', 'field2', 'combined_fields')
        readonly_fields = ('combined_fields',)
    
        def combined_fields(self, obj):
            return obj.combined_fields()
    

    If you want to store the combined_fields in the database you could also save it when you save the model:

    def save(self, *args, **kwargs):
        self.field3 = self.combined_fields()
        super(MyModel, self).save(*args, **kwargs)
    
    0 讨论(0)
  • 2020-11-30 18:56

    Django 2.1.1 The primary answer got me halfway to answering my question. It did not help me save the result to a field in my actual model. In my case I wanted a textfield that a user could enter data into, then when a save occurred the data would be processed and the result put into a field in the model and saved. While the original answer showed how to get the value from the extra field, it did not show how to save it back to the model at least in Django 2.1.1

    This takes the value from an unbound custom field, processes, and saves it into my real description field:

    class WidgetForm(forms.ModelForm):
        extra_field = forms.CharField(required=False)
    
        def processData(self, input):
            # example of error handling
            if False:
                raise forms.ValidationError('Processing failed!')
    
            return input + " has been processed"
    
        def save(self, commit=True):
            extra_field = self.cleaned_data.get('extra_field', None)
    
            # self.description = "my result" note that this does not work
    
            # Get the form instance so I can write to its fields
            instance = super(WidgetForm, self).save(commit=commit)
    
            # this writes the processed data to the description field
            instance.description = self.processData(extra_field)
    
            if commit:
                instance.save()
    
            return instance
    
        class Meta:
            model = Widget
            fields = "__all__"
    
    0 讨论(0)
  • 2020-11-30 19:01

    Either in your admin.py or in a separate forms.py you can add a ModelForm class and then declare your extra fields inside that as you normally would. I've also given an example of how you might use these values in form.save():

    from django import forms
    from yourapp.models import YourModel
    
    
    class YourModelForm(forms.ModelForm):
    
        extra_field = forms.CharField()
    
        def save(self, commit=True):
            extra_field = self.cleaned_data.get('extra_field', None)
            # ...do something with extra_field here...
            return super(YourModelForm, self).save(commit=commit)
    
        class Meta:
            model = YourModel
    

    To have the extra fields appearing in the admin just:

    1. edit your admin.py and set the form property to refer to the form you created above
    2. include your new fields in your fields or fieldsets declaration

    Like this:

    class YourModelAdmin(admin.ModelAdmin):
    
        form = YourModelForm
    
        fieldsets = (
            (None, {
                'fields': ('name', 'description', 'extra_field',),
            }),
        )
    

    UPDATE: In django 1.8 you need to add fields = '__all__' to the metaclass of YourModelForm.

    0 讨论(0)
  • 2020-11-30 19:06

    If you absolutely only want to store the combined field on the model and not the two seperate fields, you could do something like this:

    • Create a custom form using the form attribute on your ModelAdmin (https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.form)
    • Parse the custom fields in the save_formset method on your ModelAdmin (https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.save_model)

    I never done something like this so I'm not completely sure how it will work out.

    0 讨论(0)
提交回复
热议问题