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

在Django重组多对多关系

  •  3
  • Galen  · 技术社区  · 14 年前

    我在我的模型中有一个多对多的关系,我正试图在我的一页上重新组织它。

    我的网站有视频。在每一个视频页面上,我试图列出该视频中的演员,每次他们在视频中都有链接(链接将跳到视频的该部分)

    这是一个例子


    此处嵌入Flash视频

    演员。。。

    Ted smith: 1:25, 5:30
    jon jones: 5:00, 2:00
    

    这是我模型的相关部分

    class Video(models.Model):
        actor = models.ManyToManyField( Actor, through='Actor_Video' )
        # more stuff removed
    
    class Actor_Video(models.Model):
        actor = models.ForeignKey( Actor )
        video = models.ForeignKey( Video)
        time = models.IntegerField()
    

    这是我的演员视频表的样子,也许看我在做什么会更容易些。

    id     actor_id    video_id    time (in seconds)
    1        1             3        34
    2        1             3        90
    

    我觉得我必须重新组织我的视图中的信息,但我不能搞清楚。在使用djangos orm的模板中似乎不可能实现这一点。我尝试过创建字典/列表,但我运气不好。感谢您的帮助。谢谢。

    3 回复  |  直到 14 年前
        1
  •  1
  •   dguaraglia    14 年前

    我认为最具姜戈风格的方法是使用“重新组合”模板标记:

    {% regroup video.actor_video_set.all by actor as video_times %}
    {% for actor_times in video_times %}
        <li>{{ actor_times.grouper }}: # this will output the actor's name
        {% for time in actor_times %}
            <li>{{ time }}</li> # this will output the time
        {% endfor %}
        </li>
    {% endfor %}
    

    这样就可以避免在模板中使用比您想要的更多的逻辑。顺便说一句,你可以在重新组合标签上阅读 here

        2
  •  0
  •   hwjp    14 年前

    我建议将您的逻辑放在视图函数中,而不是模板中。如果我理解正确,每一页上你只有一个视频,这使得事情相当简单

    def video_view(request,video_id)
        video = Video.objects.get(pk=video_id)
        actors = Actor.objects.filter(video=video)
        #now add a custom property to each actor called times
        #which represents a sorted list of times they appear in this video
        for actor in actors:
            actor.times = [at.time for at in actor.actor_video_set.filter(video=video).order_by('time')] #check syntax here
    

    然后,在模板中,您可以通过actor.times循环:

    <ul>
    {% for actor in video.actors.all.distinct %}
        <li>{{ actor }}:
    
            <ul>
        {% for t in actor.times %} #this now returns only the times corresponding to this actor/video
                <li><a href="?time={{ t.time }}">{{ t.time }}</a></li> #these are now sorted
    

    注意-在这里编写所有代码而不使用IDE,您需要检查语法。希望它有帮助!

    对于奖励积分:将时间(视频)函数定义为actor model类的自定义函数

        3
  •  0
  •   Galen    14 年前

    我把它编成了一本时间清单词典

    actor_sets = data['video'].video_actor_set.all()
    data['actors'] = {}
    
    for actor_set in actor_sets:
        if not data['actors'].has_key( actor_set.actor ):
            data['actors'][actor_set.actor] = []
            data['actors'][actor_set.actor].append( actor_set.time )
    

    在模板中,我循环使用它,而不是在实际模板中运行查询。