代码之家  ›  专栏  ›  技术社区  ›  kovshenin

按泛型外键的Django顺序

  •  1
  • kovshenin  · 技术社区  · 14 年前

    嘿,这个很快。我有两个模型,Post和Term,我希望能够标记和分类(分类)Post以及其他(未来)模型。我的Post模型包含以下字段:title、content、published(date),我的术语声明如下:

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

    然后我有一个termrelationship模型,它将术语粘贴到Posts和其他模型上,如下所示:

    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)
    

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

    我得到一个错误,说在TermRelation中没有content\u object字段。我知道一定有办法解决。有什么想法吗?

    谢谢~K

    2 回复  |  直到 14 年前
        1
  •  2
  •   kovshenin    14 年前

    是的,我对带有连接的简单SQL查询非常正确。实际上有一些连接。这是对我有用的(django>=1.2 raw()

    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)
    

    没那么难。也许我应该用一种方法来描述关系,你觉得呢?

    更新: 我把它包装成一个静态方法,使它更通用于处理不同的内容类型和排序顺序。它仍然假设有一个名为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)
    
        2
  •  1
  •   Bernhard Vallant    14 年前

    order_by -参数被转换为数据库列/表和 content_object