如何在Django管理页面中获取实际的对象ID(在formfield_for_foreignkey中)?

Jay*_*eto 8 django django-models django-admin

我已经解决了使用此代码获取对象ID的问题:

class CompanyUserInline(admin.StackedInline):
    """
    Defines tabular rules for editing company users direct in company admin
    """
    model = CompanyUser

    def formfield_for_foreignkey(self, db_field, request, **kwargs):

        if db_field.name == "user":
            users = User.objects.filter( Q(is_superuser=False) )
            query = Q()
            for u in users:
                aux = CompanyUser.objects.filter(user=u)
                if aux.count() == 0:
                    query |= Q(pk=u.id)

            try:
                cpu = CompanyUser.objects.filter(company__id=int(request.path.split('/')[4]))
                for p in cpu:
                    query |= Q(pk=p.user.id)
            except:
                pass

            kwargs["queryset"] = User.objects.filter(query).order_by('username')

        return super(CompanyUserInline, self).formfield_for_foreignkey(db_field, request, **kwargs)
Run Code Online (Sandbox Code Playgroud)

但是,int(request.path.split('/')[4])真的很难看.我想知道如何从Django AdminModel获取id.我确定它在里面,有谁知道?

先感谢您!; d

Fiz*_*ike 13

经过一番挖掘,我们能够获取传递给管理视图的参数(在被django admin的urls.py解析之后)并使用它(self_pub_id)来获取对象:

class PublicationAdmin(admin.ModelAdmin):

    def formfield_for_manytomany(self, db_field, request, **kwargs):
        if db_field.name == "authors":
            #this line below got the proper primary key for our object of interest
            self_pub_id = request.resolver_match.args[0]

            #then we did some stuff you don't care about
            pub = Publication.objects.get(id=self_pub_id)
            kwargs["queryset"] = pub.authors.all()
        return super(PublicationAdmin, self).formfield_for_manytomany(db_field, request, **kwargs)
Run Code Online (Sandbox Code Playgroud)

更优雅的解决方案是使用接受的答案推荐并利用get_form ModelAdmin成员函数.像这样:

class ProfileAdmin(admin.ModelAdmin):
    my_id_for_formfield = None
    def get_form(self, request, obj=None, **kwargs):
        if obj:
            self.my_id_for_formfield = obj.id
        return super(ProfileAdmin, self).get_form(request, obj, **kwargs)

    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        if db_field.name == "person":
            kwargs["queryset"] = Person.objects.filter(profile=self.my_id_for_formfield)
        return super(ProfileAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
Run Code Online (Sandbox Code Playgroud)


Ber*_*ant 8

据我所知,不可能通过formfield_for_...-methods 访问当前实例,因为它们只会被调用一个字段实例!

更好的一点就是可以访问整个实例/表单get_form.您还可以在那里覆盖表单字段的查询集!

  • 请参阅http://code.djangoproject.com/browser/django/trunk/django/contrib/admin/options.py上的原始代码.如果`form`是orignal`get_form`方法返回的形式,`form.base_fields`应该是字段对象的字典! (2认同)

Maz*_* Mk 7

以下代码片段将为您提供对象 ID:

request.resolver_match.kwargs['object_id']
Run Code Online (Sandbox Code Playgroud)

示例用法:(我正在过滤显示的电话号码,仅显示客户的电话号码)

def formfield_for_foreignkey(self, db_field, request, **kwargs):
    if db_field.name == 'preferred_contact_number':
        kwargs['queryset'] = CustomerPhone.objects.filter(customer__pk=request.resolver_match.kwargs['object_id'])
    return super().formfield_for_foreignkey(db_field, request, **kwargs)
Run Code Online (Sandbox Code Playgroud)

PS:通过调试和遍历可访问变量找到它。