我如何在Django管理页面中(在formfield\u for\u foreignkey中)获取实际的对象id?

我如何在Django管理页面中(在formfield\u for\u foreignkey中)获取实际的对象id?,django,django-models,django-admin,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, *

我已经解决了使用以下代码获取正在编辑的对象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)
但是,int(request.path.split(“/”)[4])非常难看。我想知道如何从Django AdminModel获取id。我肯定它就在里面,有人知道吗


提前谢谢你;D

据我所知,无法通过
formfield\u for…
-方法访问当前实例,因为它们将仅针对单个字段实例调用


在这个逻辑中,可以访问整个实例/表单的更好的连接点是
get\u form
。您还可以覆盖表单字段的查询集

我正在处理一个类似的情况,并且意识到我从请求中需要的id,我可以从它自己的模型中获得,因为它是该模型的外键。所以它会是这样的:

cpu = CompanyUser.objects.filter(company__id=self.company_id)

或者模型的结构要求什么。

经过深入研究,我们能够获取传递到admin视图的参数(通过django admin的URL.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)
更优雅的解决方案是使用公认的答案建议,并利用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)

我通过在model.py中创建一个返回ID的属性()来实现它

models.py:

class MyModel(models.Model):
    myfield = models.CharField(max_length=75)
    ...
    def get_id(self):
        return str(self.id)
    getid = property(get_id)
admin.py:

from myapp.models import MyModel

class MyModelAdmin(admin.ModelAdmin):
    list_display = ['mylink',]
    def mylink(self, object):
        return '<a href="http://mywebsite/'+object.getid+'/">Edit</a>'
    mylink.allow_tags = True

admin.site.register(MyModel, MyModelAdmin)
从myapp.models导入MyModel
类MyModelAdmin(admin.ModelAdmin):
列表显示=['mylink',]
def mylink(自身、对象):
返回“”
mylink.allow_tags=True
admin.site.register(MyModel,MyModelAdmin)

我通过重写
change\u view()


然后您可以调用
self.object\u id
inside
formfield\u for\u foreignkey()

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

request.resolver_match.kwargs['object_id']
示例用法:(我过滤显示的电话号码,只显示客户的电话号码)


注意:通过调试和遍历可访问的变量来找到它。

一种更通用的方法可以是编写一个helper方法来获取模型实例(如果有的话),就像您通常使用(有界的)ModelForm一样,并从中检索id或任何其他属性:

from django.contrib import admin

class MyModelAdmin(admin.ModelAdmin):

    def get_instance(self, request):
        try:
            object_id = request.resolver_match.kwargs['object_id']
            obj = self.get_object(request, object_id)
        except:
            obj = None
        return obj

我在哪里可以找到一些关于get_表单的文档?我试着通过它来获取对象,但我不知道如何使用该方法覆盖表单字段的查询集=/请参阅上的原始代码。如果
form
是原始
get\u form
方法返回的表单,
form.base\u fields
应该是字段对象的字典!好啊谢谢你,伙计!我会看一看,并在这里发布解决方案。如果我做到了!再次感谢你;D你能给这个答案增加一些上下文和解释吗。这条线采用什么方法?什么课?哪个模块?很简单。我想要一种在formfield\u中为\u foreignkey使用id的方法,而不是简单地向用户显示它。同意,这并不能回答问题。嘿,赛尔夫,这是黑客!!但它是有效的。我们再次穿越了我们自己的道路。你可以存储整个对象,而不需要只存储id。不过这是一个不错的解决方案!非常感谢,您为我节省了一些时间,实际上对我来说,django 2.2.5是应要求的。resolver\u match.kwargs.get('object\u id',None)对我来说效果很好,但是如果修改后值仍然很高,要重置它,您必须在add\u视图中执行相同的操作,并设置self.object\u id=None的值这是最好的方法!类似的:
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)
from django.contrib import admin

class MyModelAdmin(admin.ModelAdmin):

    def get_instance(self, request):
        try:
            object_id = request.resolver_match.kwargs['object_id']
            obj = self.get_object(request, object_id)
        except:
            obj = None
        return obj