从Django中的相关模型访问和显示值

时间:2014-11-05 14:00:03

标签: python django django-models django-admin

我在Django(1.7)中定义了2个模型。它们如下(简化版):

from django.db import models
from django.utils import timezone
from datetime import timedelta

class ModelA(models.Model):
    email_addr = models.EmailField(max_length=100,verbose_name='Email')

class ModelB(models.Model):
    my_model = models.ForeignKey(ModelA)
    valid_until = models.DateTimeField('valid until', default=timezone.now()+timedelta(days=2))

可以看出,两个模型之间存在OneToMany关系。 1 ModelA可以有一个或多个ModelB。

在admin.py中,我有以下内容:

class ModelAAdmin(admin.ModelAdmin):
    list_display = ('id', 'email_addr')

admin.site.register(ModelA,ModelAAdmin)

我想在我的管理员中显示ModelA的每个记录,该记录显示最新相关ModelB记录的字段valid_until的值。类似的东西:

class ModelAAdmin(admin.ModelAdmin):
    most_recent_valid_until = // retrieve the related ModelB record with the most recent valid until value //
    list_display = ('id', 'email_addr', 'most_recent_valid_until')

例如,让我们说:

a)有1条ModelA记录,其值为:id:1,email_addr:foo@bar.com

b)有2条ModelB记录与ModelA的id为1的记录有关。它们如下:(id:5,valid_until:25/10/2014),(id:6,valid_until:27/10/2014)。

然后,我希望我的管理员显示如下记录列表:

1 foo@bar.com 27/10/2014

我是Python和Django的新手,所以如果我的问题非常明显,请原谅。

非常感谢!

4 个答案:

答案 0 :(得分:3)

class ModelAAdmin(admin.ModelAdmin):
    list_display = (..., 'get_valid_until')

    def get_valid_until(self, obj):
        return obj.modelb_set.last()
    get_valid_until.short_description = 'Valid until'

答案 1 :(得分:1)

list_display会查找您的ModelAdmin

的特性
class ModelAAdmin(admin.ModelAdmin):

    list_display = ('id', 'email_addr', 'most_recent_valid_until')

    def most_recent_valid_until(self, obj):
      # do your query and return the data you want displayed in this row's `most_recent_valid_until` cell

obj是ModelA实例,您可以查询它们相关的模型b实例

如果您在计算此属性时进行查询,则会在您的管理页面上执行大量查询...

答案 2 :(得分:0)

我认为你应该将外键从Model转移到Model:

class ModelA(models.Model):
    my_model = models.ForeignKey(ModelB)
    email_addr = models.EmailField(max_length=100,verbose_name='Email')

class ModelB(models.Model):
    valid_until = models.DateTimeField('valid until', default=timezone.now()+timedelta(days=2))

然后将方法添加到ModelA类:

def valid_until():
    return self.my_model.valid_until

并将list_display更改为:

list_display = ('id', 'email_addr', 'valid_until')

希望有所帮助:)

答案 3 :(得分:0)

您可以向list_display()添加自定义函数:

class ModelAAdmin(admin.ModelAdmin):   
    list_display = ('id', 'email_addr', 'most_recent_valid_until')

def most_recent_valid_until(self, obj):
    return obj.modelb_set.all().order_by('-valid_until').first()

(未测试的)