Django 查询集过滤表

django queryset filter over tables

我有如下模型:

class Node(models.Model):
    name = models.CharField(max_length=128)
    user = models.Foreignkey(User)

    class Meta:
        db_table = 'node'

class Thing(models.Model):
    user = models.ForeignKey(User)
    begin_time = models.DateTimeField()
    node = models.ManyToManyField(Course)

    class Meta:
        db_table = 'thing'

class NodeLog(models.Model):
    actor = models.ForeignKey(User)
    node = models.ForeignKey(Node, related_name='nodelog_node')
    action_time = models.DateTimeField()
    result = models.CharField(max_length=128)

    class Meta:
        db_table = 'node_log'

数据如下:

table: node
+----+-------+---------+
| id | name  | user_id |
+----+-------+---------+
|  1 | node1 | 101     |
+----+-------+---------+
|  2 | node2 | 102     |
+----+-------+---------+

table: thing
+----+---------+---------------------+
| id | user_id | begin_time          |
+----+---------+---------------------+
|  1 | 1       | 2015-01-01 03:00:00 |
+----+---------+---------------------+

table: thing_node
+----+----------+---------+
| id | thing_id | node_id |
+----+----------+---------+
|  1 | 1        | 1       |
+----+---------+----------+
|  2 | 1        | 2       |
+----+---------+----------+

table: node_log
+----+----------+---------+------------------------------+
| id | actor_id | node_id | action_time        |  result |
+----+----------+---------+------------------------------+
|  1 | 101      | 1       |2015-01-01 01:00:00 |  agree  |
|  2 | 102      | 2       |2015-01-01 02:00:00 |  agree  |
|  3 | 101      | 1       |2015-01-01 04:00:00 |  agree  |
+----+----------+---------+--------------------+---------+

如果有人同意了,他的action_time大于begin_time,他就不能再同意了,所以我是这样排除的:

Thing.objects.filter(***).exclude(node__nodelog_node__action_time__gt=F('begin_time'), node__nodelog_node__actor=request.user)

request.user为102,结果为[]。

的结果
Thing.objects.filter(***)

说得对,有什么建议吗?谢谢!

我认为问题可能在于 exclude 的行为不像 filter。在 exclude 中,条件不需要保持在一起(即不是 and-ed)

from the docs

The behavior of filter() for queries that span multi-value relationships, as described above, is not implemented equivalently for exclude(). Instead, the conditions in a single exclude() call will not necessarily refer to the same item. For example, the following query would exclude blogs that contain both entries with “Lennon” in the headline and entries published in 2008:

Blog.objects.exclude(
    entry__headline__contains='Lennon',
    entry__pub_date__year=2008,
) However, unlike the behavior when using filter(), this will not limit blogs based on entries that satisfying both conditions. In order

to do that, i.e. to select all blogs that do not contain entries published with “Lennon” that were published in 2008, you need to make two queries:

Blog.objects.exclude(
    entry=Entry.objects.filter(
        headline__contains='Lennon',
        pub_date__year=2008,
    ),
)