在Django中访问具有外键关系的对象?

时间:2013-06-20 19:54:16

标签: python django foreign-key-relationship podcast

我目前正在尝试修改django-podcast模块,以便静态提供播客的xml文件,而不是在每次请求时生成。

每次修改,创建或删除剧集时,我都会尝试重写频道的xml文件,并且我正在使用django signals。我想做的就是这样......

from django.db.models.signals import post_save, post_delete
from django.template.loader import render_to_string

def update_xml_file(sender, **kwargs):
    f = open('channelrss.xml', 'w')
    f.write(render_to_string('podcast/show_feed.html', {'object': sender.show}))
    f.close()

class Show(models.Model):
    ...

class Episode(models.Model):
    post_save.connect(update_xml_file)
    post_delete.connect(update_xml_file)
    ...
    show = models.ForeignKey(Show)
    ...

我一直遇到的问题是sender.show是ReverseSingleRelatedObjectDescriptor而不是Show类的实际实例。我还尝试使用sender.pk作为主键值重新加载发送方对象...

Episode.objects.filter(pk=sender.pk)

但显然sender.pk返回property object而不是整数或字符串,我不知道如何得到它的值,所以我想我有两个问题。

如何检索与Show相关联的Episode实例?什么是property object以及为什么sender.pk会返回它?

提前感谢您的回复!

约什

2 个答案:

答案 0 :(得分:1)

您可以尝试:

def update_xml_file(sender, instance=False, **kwargs):
    f = open('channelrss.xml', 'w')
    f.write(render_to_string('podcast/show_feed.html', {'object': instance.show}))
    f.close()

instance.show.name_field为模型的name_field时。

答案 1 :(得分:0)

我终于明白了!这个问题是由于我对发送给我的信号处理程序的参数缺乏了解。

发送给我的处理程序的sender参数实际上是一个类对象,而不是实例本身。为了检索实例本身,我需要使用kwargs['instance']并为了检索Show实例,我只使用了kwargs['instance'].show

因此,我认为我了解property object问题的来源。如果我错了,请纠正我,但在尝试访问“类”对象而不是“类的实例”对象时,属性不会定义为字符串或整数值,而是需要定义的属性对象。

另外作为补充说明,signal.connect()函数不需要在类的模型中定义,并且上面写的方式有点欺骗。上面连接的方式将监听任何对象的保存或删除信号。为了将函数与仅来自Episode对象的信号相关联,我应该将其写为......

post_save.connect(update_xml_file, sender=Episode)
post_delete.connect(update_xml_file, sender=Episode)

或使用Django's signal documentation所示的装饰器。

再次感谢您的帮助!

约什