【问题标题】:Customize Django Admin: Add More Than One Default Inline on Parent Add_View自定义 Django Admin:在父 Add_View 上添加多个默认内联
【发布时间】:2012-06-13 22:02:59
【问题描述】:

我有一个管理模型,其中包含一些内联模型(完整类请参见下面的 ResourceUserAdmin 模型):

    inlines = [ 
            ResourceLocationInlineAdmin ,
            ResourceCategoryInlineAdmin , 
            ResourceStageInlineAdmin ,
          ]

当用户点击创建一个新的 ResourceUserAdmin 我希望类 ResourceCategoryInlineAdmin 的内联获取初始值 - 请注意,这些关系不会保存到数据库。我试图覆盖 add_view 函数的部分以获得我想要的,但我不知道如何将多个内联表单传递回父级。

关于如何实现这一点的任何想法?

模型

class ResourceUserAdmin( admin.ModelAdmin ):
    inlines = [ 
            ResourceLocationInlineAdmin ,
            ResourceCategoryInlineAdmin , 
            ResourceStageInlineAdmin ,
          ]

    list_display = ( 
                 'user' , 
                 'name' ,
                 'state' ,
                 'email' ,
                 'website' ,
                 'phone' ,
                 'logo_url_link',
    )

    search_fields = ( 'name' , 'email' , 'website'  )

    list_filter = ( 'name' , 'state' , 'email' , 'website' )

    ordering = ( 'name', )

     fields = ( 
             'user' , 
             'name' ,
             'state' ,
             'email' ,
             'website' ,
             'phone' ,
             'logo' ,
             'ideal_candidate',
    )
admin.site.register( ResourceUser, ResourceUserAdmin )

这是我想默认创建的内联模型:

class ResourceCategoryInlineAdmin( admin.StackedInline ):
    model = ResourceCategory
    extra = 0

class ResourceCategoryAdmin( admin.ModelAdmin ):
    list_display = ( 'user' ,
                     'category' , )

    ordering = ( 'user' , )
    fields = ( 'user' , 'category' )

    def formfield_for_foreignkey( self, db_field, *args, **kwargs ):
        if isinstance( db_field, models.ForeignKey ):
            if db_field.name == 'category':
                kwargs['widget'] = forms.RadioSelect()
        return super( ResourceCategoryAdmin, self).formfield_for_foreignkey( db_field, **kwargs )

admin.site.register( ResourceCategory, ResourceCategoryAdmin )

【问题讨论】:

    标签: django django-admin


    【解决方案1】:

    这是一种解决方案,虽然不是我真正想要使用的选项。您可以通过覆盖整个 add_view 函数并为表单集中的每个表单设置初始属性来做到这一点(查找下面的覆盖注释)

    def add_view(self, request, form_url='', extra_context=None):
        "The 'add' admin view for this model."
        model = self.model
        opts = model._meta
    
        if not self.has_add_permission(request):
            raise PermissionDenied
    
        ModelForm = self.get_form(request)
        formsets = []
        if request.method == 'POST':
            form = ModelForm(request.POST, request.FILES)
            if form.is_valid():
                new_object = self.save_form(request, form, change=False)
                form_validated = True
            else:
                form_validated = False
                new_object = self.model()
            prefixes = {}
            for FormSet, inline in zip(self.get_formsets(request), self.inline_instances):
                prefix = FormSet.get_default_prefix()
                prefixes[prefix] = prefixes.get(prefix, 0) + 1
                if prefixes[prefix] != 1:
                    prefix = "%s-%s" % (prefix, prefixes[prefix])
                formset = FormSet(data=request.POST, files=request.FILES,
                                  instance=new_object,
                                  save_as_new="_saveasnew" in request.POST,
                                  prefix=prefix, queryset=inline.queryset(request))
                formsets.append(formset)
            if all_valid(formsets) and form_validated:
                self.save_model(request, new_object, form, change=False)
                form.save_m2m()
                for formset in formsets:
                    self.save_formset(request, form, formset, change=False)
    
                self.log_addition(request, new_object)
                return self.response_add(request, new_object)
        else:
            # Prepare the dict of initial data from the request.
            # We have to special-case M2Ms as a list of comma-separated PKs.
            initial = dict(request.GET.items())
            for k in initial:
                logger.info( "for k in initial, k = %s" % k )
                try:
                    f = opts.get_field(k)
                except models.FieldDoesNotExist:
                    continue
                if isinstance(f, models.ManyToManyField):
                    initial[k] = initial[k].split(",")
            form = ModelForm(initial=initial)
            prefixes = {}
            for FormSet, inline in zip(self.get_formsets(request),
                                       self.inline_instances):
                prefix = FormSet.get_default_prefix()
                prefixes[prefix] = prefixes.get(prefix, 0) + 1
                if prefixes[prefix] != 1:
                    prefix = "%s-%s" % (prefix, prefixes[prefix])
    
                formset = FormSet(instance=self.model(), prefix=prefix, queryset=inline.queryset(request))
    
                #
                #
                # override the inlines of my choice
                # to create initial values
                #
                #
                if inline.__class__.__name__ == 'ResourceCategoryInlineAdmin':
                    for frm, category in zip( formset, Category.objects.all() ):
                       frm.fields['category'].initial = category
    
                formsets.append(formset)
    
        adminForm = helpers.AdminForm(form, list(self.get_fieldsets(request)),
            self.prepopulated_fields, self.get_readonly_fields(request),
            model_admin=self)
        media = self.media + adminForm.media
    
        inline_admin_formsets = []
        for inline, formset in zip(self.inline_instances, formsets):
            fieldsets = list(inline.get_fieldsets(request))
            readonly = list(inline.get_readonly_fields(request))
            inline_admin_formset = helpers.InlineAdminFormSet(inline, formset,
                fieldsets, readonly, model_admin=self)
            inline_admin_formsets.append(inline_admin_formset)
            media = media + inline_admin_formset.media
    
        context = {
            'title': _('Add %s') % force_unicode(opts.verbose_name),
            'adminform': adminForm,
            'is_popup': "_popup" in request.REQUEST,
            'show_delete': False,
            'media': mark_safe(media),
            'inline_admin_formsets': inline_admin_formsets,
            'errors': helpers.AdminErrorList(form, formsets),
            'root_path': self.admin_site.root_path,
            'app_label': opts.app_label,
        }
        context.update(extra_context or {})
        return self.render_change_form(request, context, form_url=form_url, add=True)
        #return super(ResourceUserAdmin, self).add_view(request, form_url=form_url, extra_context=extra_context)
    

    【讨论】:

      猜你喜欢
      • 2013-11-17
      • 1970-01-01
      • 2018-02-22
      • 2018-10-11
      • 1970-01-01
      • 2017-02-12
      • 2021-06-05
      • 2011-01-11
      • 2011-10-17
      相关资源
      最近更新 更多