简体   繁体   English

从外键获取值 Python model

[英]Obtaining values from a foreign key Python model

Let's say I have these models/classes:假设我有这些模型/类:

class User(models.Model):
    id = models.AutoField. . .
    group = models.ForeignKey(
        Group,
        . . .
    )
    . . .

class Group(models.Model):
    id = models.AutoField. . .
    name = models.CharField. . .
    . . .

In a custom logging function called when there is a change being made, I do this:在进行更改时调用的自定义日志记录 function 中,我这样做:

obj = # object/model being updated; in this case: User
old_values = {}
new_values = {}
for i in range(len(form.changed_data)):
    vname = obj._meta.get_field(form.changed_data[i]).verbose_name

    old_values.update(
        { vname: form[form.changed_data[i]].initial }
    )
    new_values.update(
        { vname: form.cleaned_data[form.changed_data[i]] }
    )

That leads to this output:这导致了这个 output:

old_values = {'Group': 2}

new_values = {'Group': <Group: New Group Name>}

Looks like form.initial uses the id while form.cleaned_data uses some kind of unsightly object name format.看起来form.initial使用idform.cleaned_data使用某种难看的 object 名称格式。

Neither are desired.两者都不需要。 I want the output to look like this:我希望 output 看起来像这样:

old_values = {'Group': 'Old Group Name'}

new_values = {'Group': 'New Group Name'}

How do I do this?我该怎么做呢? I cannot explicitly import the model name and use it.我无法显式导入 model 名称并使用它。 User and Group are merely two of dozens of models that must be treated non-explicitly in this generic logging function. UserGroup只是在此通用日志记录 function 中必须非显式处理的数十个模型中的两个。

I've tried apps.get_model() , get_object_or_404() , and other methods, but nothing has been working for me so far.我已经尝试过apps.get_model()get_object_or_404()和其他方法,但到目前为止没有任何效果。

The value of Foreign Key in the default form is the PK of the model. Foreign Key默认形式的值为model的PK。

# old_values = {'Group': 2}
group = Group.objects.get(pk=old_values['Group'])
new_values = {'Group': group.name}

I still do not know how to do what I tried above, but I solved my problem another way.我仍然不知道如何做我上面尝试过的事情,但我用另一种方式解决了我的问题。

To start, each object has a meta variable that references its object class. Using that, we can obtain a list of fields for any given object.首先,每个 object 都有一个引用其 object class 的元变量。使用它,我们可以获得任何给定 object 的字段列表。

for field in obj._meta.get_fields():
    value = getattr(obj, field.name, None)

You can check each field for whatever specifications you have, like if they should be ignored like ID fields, should be censored like password fields, or is a ManyToManyField etc.您可以检查每个字段的任何规范,例如它们是否应该像 ID 字段一样被忽略,是否应该像密码字段一样被审查,或者是 ManyToManyField 等。

if isinstance(field, ManyToManyField):
    values = []
    for obj in value.all():
        values.append(str(obj))

Depending on what the value is, you may want repr(value) , str(value) , str(object) , or just plain value .根据值是什么,您可能需要repr(value)str(value)str(object)或只是简单的value

What I did was create a function get_values(object) that utilized the above to return a standardized list of stuff.我所做的是创建一个 function get_values(object),它利用上面的方法返回一个标准化的东西列表。 Sending that function the objects during the logging process worked just fine.在记录过程中发送 function 对象工作得很好。

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

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