在Django中创建活动流

时间:2013-11-15 11:41:37

标签: django django-models

我需要生成用户流。我在Django 1.5中使用内容类型框架,我正在使用第三方软件包'Phileo(喜欢),Django-Posts(发布),Dialogos(评论)

我有帖子,评论,赞,分享,连接以及事件数据库模型

这是我的帖子模型的样子

class Post(models.Model):
      text = models.TextField(_("Text"))
      .... # no GenericForeignKey

这是我的评论模型

class Comment(models.Model):
    content_type = models.ForeignKey(ContentType)
    object_id = models.IntegerField()
    content_object = GenericForeignKey()

    comment = models.TextField()

这是我的UserEvent模型

class UserEvent(models.Model):
    event = models.ForeignKey(Event)
    data_type = models.ForeignKey(ContentType, null=True)
    data_id = models.PositiveIntegerField(null=True)
    data_object = generic.GenericForeignKey('data_type', 'data_id')


class Event(models.Model):
    eventId = models.CharField(max_length=100)
    title = models.CharField(max_length=200, default="untitled")

UserEvent包含用户的所有活动,例如(loggedIn,loggedOut,SignUp,Create Post,Post on Post,Like a Post等)。

Q - 1 * 从中创建活动流的最佳方法是什么。 *

如果我做feeds = UserEvents.object.all()这样的事情,我会在模板中做..

{% for item in feeds%}
     {% if item.data_type.name == 'post' %}
         {{ item.data_object.text }}
         <!-- Show post -->
     {% endif %}
     {% if item.data_type.name == 'connection' %}
         <!-- Show User 3 and User 5 are now friend -->
     {% endif %}
{% endfor %}

但问题是Post没有Comments模型的外键。

问题2 - 那么我该怎样才能显示与帖子相关的评论。我真的不想使用' 模板标签 '。另一个解决方法是我将comments = generic.GenericRelation(Comment)放在Post Model中但我想要是通用的(我相信UserEvent拥有所有相关项目)因为将来我会有更多的模型..比如'Share','Tag', '喜欢'等等。我需要将所有通用关系放在我的POST中。

class Like(models.Model):

    sender = models.ForeignKey(AUTH_USER_MODEL, related_name="liking")

    receiver_content_type = models.ForeignKey(ContentType)
    receiver_object_id = models.PositiveIntegerField()
    receiver = generic.GenericForeignKey(
        ct_field="receiver_content_type",
        fk_field="receiver_object_id"
    )

2 个答案:

答案 0 :(得分:0)

我的方法是在模型中完成所有操作。我在用户模型中创建了一个方法,如:

class UserEvent(models.Model):
    user = models.ForeignKey(User)
    event = models.ForeignKey(Event)
    data_type = models.ForeignKey(ContentType, null=True)
    data_id = models.PositiveIntegerField(null=True)
    data_object = generic.GenericForeignKey('data_type', 'data_id')


  def record_event(self, event, obj):

       UserEvent.objects.create(user=self, event=event, data_type=ContentType.objects.get_for_model(obj), data_id=obj.id)

然后在其他模型的保存方法中:

def save(self, *args, **kwargs):

    # only record on creating a new post
    if not self.id:
        self.user.record_event(self.user, event=<not sure where you event from>, )

    super(Post, self).save(*args, **kwargs)

使用活动日志中的内容类型字段可以使其更加复杂。 这种方法的一个好处是它使测试变得更加容易,因为您只需测试模型而无需测试视图。

答案 1 :(得分:0)

在django应用程序中创建模型之间关系的原因之一是有助于使用查询检索这些模型的效率。

  

Q - 1 从中创建活动流的最佳方法是什么。

UserEvent模型巧妙地封装了您应用的这种行为。

显示的代码段非常好,也可以将条件移动到另一个模板,这样就可以在网站的其他部分重复使用它。

类似的东西:

 {% for item in feeds%}
     {% include "display_feed.html" %}
 {% endfor %}

<强> display_feed.html:

 {% if item.data_type.name == 'post' %}
     {{ item.data_object.text }}
     <!-- Show post -->
 {% endif %}
 {% if item.data_type.name == 'connection' %}
     <!-- Show User 3 and User 5 are now friend -->
 {% endif %}
  

Q-2 但问题是Post没有注释模型的外键。

我不完全确定您网站的结构,但我建议您从ForeignKeyComment以另一种方式创建Post

类似的东西:

class Comment(models.Model):
    content_type = models.ForeignKey(ContentType)
    object_id = models.IntegerField()
    content_object = GenericForeignKey()
    post = models.ForeignKey(Post)        

    comment = models.TextField()

这样就可以检索给定帖子的所有评论,因为它们是related-objects

post_comments = Post.comment_set.all()

如果Comment个对象不仅仅是Posts,那么这可以成为一般关系。

您未来的所有型号“分享”,“标记”,“喜欢”等也可以使用相同的外键,并且可以以相同的方式访问。这也适用于模板:

{% for item in post.comment_set.all %}
    {% include "display_comment.html" %}
{% end for %} 
{% for item in post.tag_set.all %}
    {% include "display_tag.html" %}
{% end for %} 

恕我直言,UserEvent模型与检索评论的活动无关,因此不必在此处使用。 这似乎是一个稍微简单的答案,但通常在django中,简单的答案是最有效,最快速的实施和最好的;)。