简体   繁体   English

Django如何显示 <bound method … > &gt;在django-admin中将对象作为字符串对象?

[英]How does Django display a <bound method … >> object as a string object in django-admin?

How does Django translate this <bound method Child.parent_identity of <Child: >> object in a string object, and displays it as such in my django-admin "inline" Child class idparent field ? Django如何将字符串对象中<bound method Child.parent_identity of <Child: >>对象的<bound method Child.parent_identity of <Child: >>转换为字符串对象,并在我的django-admin“ inline” Child class idparent字段中显示它? What does Django do ? Django是做什么的?

I have the following application structure: 我具有以下应用程序结构:

##========================models.py
...
from django_extensions.db.fields import UUIDField

class Parent(models.Model):
    id           = UUIDField(primary_key=True)

class Child(models.Model):
    parent      = models.ForeignKey(Parent)
    idparent    = models.CharField(max_length=100)
    def parent_identity(self):
        return self.parent_id

#========================admin.py
class ChildForm(forms.ModelForm):
    class Meta:
        model   = Child
        exclude = []
    def __init__(self, *args, **kwargs):
        super(ChildForm, self).__init__(*args, **kwargs)
        #print self.instance.parent_identity
        self.initial['idparent']   = self.instance.parent_identity        

class ChildInline(admin.TabularInline):
    model = Child
    extra = 1
    form  = ChildForm

class ParentAdmin(admin.ModelAdmin):
    exclude = []
    inlines = [ChildInline]
    #list_display, etc
admin.site.register(Parent,ParentAdmin)

My inline idparent field displays the Parent id field CORRECTLY in the admin inline interface. 我的内联idparent字段在admin内联界面中正确显示了Parent id字段。 Being a newbie, it's magic for me, because self.instance.parent_identity is initially not a string object. 作为新手,这对我来说是神奇的,因为self.instance.parent_identity最初不是字符串对象。

print self.instance.parent_identity
#it prints  : <bound method Child.parent_identity of <Child: >>

But how to explictly print the string content as follows 但是如何如下显式打印字符串内容

>>print self.instance.parent_identity
#would print  : fffeee29-7ac6-42eb-8a8d-eb212d2365ff

That is, how to get it so as to deal with it in the ChildForm class ? 也就是说,如何获取它以便在ChildForm类中对其进行处理?

UPDATE UPDATE

I do not mind specifically about "UUID in the form when the instance hasn't been created yet" and i do not want to provide an initial value myself. 我并不特别在意“尚未创建实例时表单中的UUID”,我也不想自己提供初始值。

I want my still empty (extra) Child fields (one field in my example code: idparent) to contain by default something which is Parent variable. 我希望我仍然空的(额外的)子字段(示例代码中的一个字段:idparent)默认包含父变量。

Is it possible ? 可能吗 ?

Django templates automatically call any object that is callable; Django模板会自动调用任何可调用的对象。 eg the callable() function returns True when you pass the object in. From the Variables section in the template documentation : 例如,当您传入对象时, callable()函数将返回True在模板文档Variables部分中

If the resulting value is callable, it is called with no arguments. 如果结果值是可调用的,则不带参数调用它。 The result of the call becomes the template value. 调用的结果成为模板值。

Bound methods are callable, so instead of using self.instance.parent_identity , the template uses the output of self.instance.parent_identity() . 绑定方法是可调用的,因此模板使用self.instance.parent_identity()的输出,而不是使用self.instance.parent_identity

In your own code, you generally already know that something is a method and you call it explicitly: 在您自己的代码中,您通常已经知道某种东西是一种方法,并且您明确地调用它:

def __init__(self, *args, **kwargs):
    super(ChildForm, self).__init__(*args, **kwargs)
    self.initial['idparent']   = self.instance.parent_identity()

You can treat the parent_identity method as an attribute; 您可以将parent_identity方法视为属性; have Python call it automatically without you having to call it explicitly. 让Python自动调用它,而无需显式调用它。 If you never have to pass in an argument, then that might make sense. 如果您永远不必传递参数,那可能很有意义。 You do this by decorating the method with the @property decorator : 您可以通过使用@property装饰器装饰该方法来实现:

class Child(models.Model):
    parent      = models.ForeignKey(Parent)
    idparent    = models.CharField(max_length=100)

    @property
    def parent_identity(self):
        return self.parent_id

at which point self.instance.parent_identity will give you the return value of that method. 此时self.instance.parent_identity将为您提供该方法的返回值。

Take into account that the UUIDField only is given a value on pre-save ; 考虑到在预保存时仅给UUIDField一个值; it'll be None until the object is saved in a database. 在将对象保存到数据库之前,它将一直为None

If you really wanted to UUID in the form when the instance hasn't been created yet, you'll have to provide an initial value yourself: 如果您真的想在尚未创建实例的情况下以表单形式使用UUID,则必须自己提供一个初始值:

import uuid 

class ParentAdmin(admin.ModelAdmin):
    exclude = []
    inlines = [ChildInline]

    def __init__(self, *args, **kwargs):
        super(ParentAdmin, self).__init__(*args, **kwargs)
        self.fields['id'].initial = uuid.uuid4

You are calling a function, which means you need to use it as such: 您正在调用一个函数,这意味着您需要这样使用它:

self.initial['idparent']   = self.instance.parent_identity()

Alternately you could wrap it with the @property decorator and continue using it as you are, notice that you need to use self.parent.id if you want to access the parent's id : 或者,你可以用它包装@property装饰,并继续使用它,你是, 你需要使用的通知 self.parent.id 如果要访问父的id:

class Child(models.Model):
    parent      = models.ForeignKey(Parent)
    idparent    = models.CharField(max_length=100)

    @property
    def parent_identity(self):
        return self.parent.id

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM