Django按通用外键排序

时间:2010-10-19 10:52:22

标签: python django generics

嘿,这是一个快速的。我有两个模型,Post和Term,我希望能够标记和分类(分类)帖子以及其他(未来)模型。我的帖子模型有以下字段:标题,内容,发布(日期)和我的术语声明如下:

class Term(models.Model):
    taxonomy = models.CharField(max_length=255)
    name = models.CharField(max_length=255)
    slug = models.SlugField(max_length=50)

然后我有一个TermRelation模型,它将条款粘贴到帖子和其他模型,如下所示:

class TermRelation(models.Model):
    term = models.ForeignKey(Term)
    object_id = models.PositiveIntegerField()
    content_type = models.ForeignKey(ContentType)
    content_object = generic.GenericForeignKey()

一切都按预期工作但我的问题如下。我想创建某个类别中的帖子存档,并按发布日期对帖子进行排序。这就是我想要做的事情:

ctype = ContentType.objects.get_for_model(Post)
relations = TermRelation.objects.filter(content_type__pk=ctype.id)

它工作正常,虽然它按照我猜的关系PK排序。当我尝试执行以下操作时:

relations = TermRelation.objects.filter(content_type__pk=ctype.id).order_by('content_object__published')

我收到错误消息,说明TermRelation中没有content_object字段。我知道必须有办法解决它。有什么想法吗?

谢谢~K

2 个答案:

答案 0 :(得分:2)

是的,我对使用连接的简单SQL查询非常正确。实际上有几个加入。这对我有用(对于raw()方法,django> = 1.2)

data = {
    'posts': Post._meta.db_table,
    'relations': TermRelation._meta.db_table,
    'terms': Term._meta.db_table,
    'tag_id': tag.id
}

posts = Post.objects.raw('SELECT %(posts)s.* FROM %(posts)s JOIN %(relations)s ON %(posts)s.id = %(relations)s.object_id JOIN %(terms)s ON %(relations)s.term_id = %(terms)s.id WHERE %(terms)s.id = %(tag_id)s ORDER BY %(posts)s.published DESC' % data)

不是那么难。也许我应该把它包装在TermRelation的方法中,您怎么看?

更新:我确实将其包装成静态方法,并使其更具通用性,以处理不同的内容类型和排序顺序。它仍然假设有一个名为content_type_id的字段,如果ContentType上有外键,则默认创建该字段。这是代码:

@staticmethod
def get_objects_by_term_id(model=None, taxonomy=None, term_id=None, order_by='NULL'):
    data = {
        'objects': model._meta.db_table,
        'content_type': ContentType.objects.get_for_model(model).id,
        'relations': TermRelation._meta.db_table,
        'terms': Term._meta.db_table,
        'term_id': term_id,
        'order_by': ' ORDER BY %s ' % order_by
    }

    return model.objects.raw('SELECT %(objects)s.* FROM %(objects)s JOIN %(relations)s ON %(objects)s.id = %(relations)s.object_id AND %(relations)s.content_type_id = %(content_type)s JOIN %(terms)s ON %(relations)s.term_id = %(terms)s.id WHERE %(terms)s.id = %(term_id)s %(order_by)s' % data)

答案 1 :(得分:1)

据我所知,django无法实现这一点,因为order_by - 参数被转换为数据库列/表,content_object不会像这样退出数据库。这也是您必须使用object_id / content_type ...

进行内容类型查找的原因