用于在admin中添加和更改页面的不同字段

ale*_*rsh 21 python django django-admin

我的admin.py中有以下类的django应用程序:

class SoftwareVersionAdmin(ModelAdmin):
    fields = ("product", "version_number", "description",
      "media", "relative_url", "current_version")
    list_display = ["product", "version_number", "size",
      "current_version", "number_of_clients", "percent_of_clients"]
    list_display_links = ("version_number",)
    list_filter = ['product',]
Run Code Online (Sandbox Code Playgroud)

我希望这些文件用于添加页面,但不同的字段用于更改页面.我怎样才能做到这一点?

小智 29

这是一个老问题,但我想补充一点,可以为此目的修改add_view和change_view方法:

class SoftwareVersionAdmin(ModelAdmin):
     ...
     def add_view(self,request,extra_content=None):
         self.exclude = ('product','version_number',)
         return super(SoftwareVersionAdmin,self).add_view(request)

     def change_view(self,request,object_id,extra_content=None):
         self.exclude = ('product','description',)
         return super(SoftwareVersionAdmin,self).change_view(request,object_id)
Run Code Online (Sandbox Code Playgroud)

  • 这比目前接受的答案更好,更清晰. (4认同)

sha*_*nyu 27

首先看一下ModelAdmin类的来源get_formget_formsets位于的方法django.contrib.admin.options.py.您可以覆盖这些方法并使用kwargs来获得所需的行为.例如:

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)
Run Code Online (Sandbox Code Playgroud)


rad*_*tek 5

使用上述解决方案,我无法在Django 1.6.5中正常工作。因此,我尝试创建表单,并让get_form为这些预定义的表单提供服务,具体取决于对象是否存在:

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)
Run Code Online (Sandbox Code Playgroud)

forms.py:从Django导入,从模型导入项目

class ProjectAddForm(forms.ModelForm):

    test = forms.Field()

    class Meta:
        model = Project


class ProjectEditForm(forms.ModelForm):

    class Meta:
        model = Project
        fields = ("name", 'slug')
Run Code Online (Sandbox Code Playgroud)

管理员

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)
Run Code Online (Sandbox Code Playgroud)

现在,我可以在clean表单中截取非持久性测试字段,并按我的意愿进行操作,只需在ProjectAddForm中覆盖clean即可:

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
Run Code Online (Sandbox Code Playgroud)