e1ad15011d2d8d5e54123eee0410a4d57eecbfbd
4 from sqlalchemy
import func
6 class Discussion(Entity
):
7 """Represents a collection of comments attached to some other object."""
9 comments
= OneToMany('Comment', order_by
='left')
11 class Comment(Entity
):
12 time
= Field(DateTime
, default
=datetime
.datetime
.now
)
13 text
= Field(Unicode(65536))
15 # Comments are a tree, and are stored as a nested set, because:
16 # - It's easy to get a subtree with a single query.
17 # - It's easy to get a comment's depth.
18 # - It's easy to sort comments without recursion.
19 # The only real disadvantage is that adding a comment requires a quick
20 # update of all the following comments (in post-order), but that's rare
21 # enough that it shouldn't be a problem.
22 left
= Field(Integer
, index
=True)
23 right
= Field(Integer
)
25 discussion
= ManyToOne('Discussion')
26 user
= ManyToOne('User')
28 def __init__(self
, parent
=None, **kwargs
):
29 """Constructor override to set left/right correctly on a new comment.
31 super(Comment
, self
).__init__(**kwargs
)
33 # Keep the comment count updated
34 self
.discussion
.count
+= 1
37 # Parent comment given. Add this comment just before the parent's
39 self
.left
= parent
.right
40 self
.right
= parent
.right
+ 1
42 # ...then adjust all rightward comments accordingly
43 Comment
.query
.filter(Comment
.discussion
== self
.discussion
) \
44 .filter(Comment
.right
> parent
.right
) \
45 .update({ Comment
.left
: Comment
.left
+ 2,
46 Comment
.right
: Comment
.right
+ 2 })
48 # And, finally, update the parent's right endpoint
52 query
= session
.query(func
.max(Comment
.right
)) \
53 .filter(Comment
.discussion
== self
.discussion
)
54 (max_right
,) = query
.one()
57 # No comments yet. Use 1 and 2
61 self
.left
= max_right
+ 1
62 self
.right
= max_right
+ 2