different fields for add and change pages in admin

前端 未结 9 741
日久生厌
日久生厌 2020-12-05 00:37

I have a django app with the following class in my admin.py:

class SoftwareVersionAdmin(ModelAdmin):
    fields = (\"product\", \"version_number\", \"descrip         


        
相关标签:
9条回答
  • 2020-12-05 01:07

    I couldn't get this working in django 1.6.5 using the above solutions. So I tried creating forms and having get_form serve those pre-defined forms depending on if the object exists or not:

    models.py:

    from django.db import models
    
    class Project(models.Model):
        name = models.CharField('Project Name', max_length=255)
        slug = models.SlugField('Project Slug', max_length=255, unique=True)
    

    forms.py: from django import forms from models import Project

    class ProjectAddForm(forms.ModelForm):
    
        test = forms.Field()
    
        class Meta:
            model = Project
    
    
    class ProjectEditForm(forms.ModelForm):
    
        class Meta:
            model = Project
            fields = ("name", 'slug')
    

    admin.py

    from django.contrib import admin
    from models import Project
    from forms import ProjectAddForm, ProjectEditForm
    
    
    class ProjectAdmin(admin.ModelAdmin):
    
        def get_form(self, request, obj=None, **kwargs):
            # Proper kwargs are form, fields, exclude, formfield_callback
            if obj:
                self.form = ProjectEditForm
            else:
                self.form = ProjectAddForm
            return super(ProjectAdmin, self).get_form(request, obj, **kwargs)
    
    
    admin.site.register(Project, ProjectAdmin)
    

    Now I can intercept the non-persistent test field in the forms clean and do as I wish with it, just overwrite clean in the ProjectAddForm:

    def clean(self):
        cleaned_data = super(ProjectAddForm, self).clean()
        test = cleaned_data.get("test")
        # Do logic here
        #raise forms.ValidationError("Passwords don't match.")
        return cleaned_data
    
    0 讨论(0)
  • 2020-12-05 01:08

    This is how it's done in Django 1.10. Just override get_form and return add_form when object is None:

    class FoobarAddForm(forms.ModelForm):
        class Meta:
            model = Foobar
            fields = ['some_field',]
    
    @register(Foobar)
    class AdminFoobar(admin.ModelAdmin):
        add_form = FoobarAddForm
    
        def get_form(self, request, obj=None, **kwargs):
            defaults = {}
            if obj is None:
                defaults['form'] = self.add_form
            defaults.update(kwargs)
            return super(AdminFoobar, self).get_form(request, obj, **defaults)
    
    0 讨论(0)
  • First have a look at source of ModelAdmin class' get_form and get_formsets methods located in django.contrib.admin.options.py. You can override those methods and use kwargs to get the behavior you want. For example:

    class SoftwareVersionAdmin(ModelAdmin):
        def get_form(self, request, obj=None, **kwargs):
            # Proper kwargs are form, fields, exclude, formfield_callback
            if obj: # obj is not None, so this is a change page
                kwargs['exclude'] = ['foo', 'bar',]
            else: # obj is None, so this is an add page
                kwargs['fields'] = ['foo',]
            return super(SoftwareVersionAdmin, self).get_form(request, obj, **kwargs)
    
    0 讨论(0)
提交回复
热议问题