开发者

How to join three many-to-many models with a double-join condition

I want to execute this query of three models/tables:

-- get all items that don't have a status for this member
SELECT  i.*
FROM
 mock_item i
 LEFT JOIN mock_itemstatusmember ism ON i.id = ism.item_id AND ism.member_id = 2

WHERE
 ism.id IS NULL

Here are how my models look:

from django.db import models

# think status as a status
class Member(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=255)

class Status(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=255)
    no = models.SmallIntegerField()

class Item(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=255)
    status = models.ManyToManyField(Status, through='ItemStatusMember')
    member = models.ManyToManyField(Member, through='ItemStatusMember')    


class ItemStatusMember(models.Model):
    """
    Table that keeps job statuss information for a user.
    Tides Items with Members with Statuss
    """
    id = models.AutoField(primary_key=True)
    member = models.ForeignKey(Member)
    status = models.ForeignKey(Status)
    item = models.ForeignKey(Item)

And their database sample data:

mysql> select *  from mock_member;
+----+--------+
| id | name   |
+----+--------+
|  1 | Stefan |
|  2 | Alex   |
|  3 | Diana  |
+----+-------开发者_如何学编程-+
3 rows in set (0.00 sec)

mysql> select *  from mock_status;
+----+---------+----+
| id | name    | no |
+----+---------+----+
|  1 | Pending |  1 |
|  2 | Success |  2 |
+----+---------+----+
2 rows in set (0.00 sec)

mysql> select *  from mock_item;
+----+----------------+
| id | name           |
+----+----------------+
|  1 | My first item  |
|  2 | My second item |
|  3 | My third item  |
+----+----------------+
3 rows in set (0.00 sec)

mysql> select *  from mock_itemstatusmember;
+----+-----------+-----------+---------+
| id | status_id | member_id | item_id |
+----+-----------+-----------+---------+
|  1 |         1 |         1 |       1 |
|  2 |         2 |         1 |       2 |
|  3 |         1 |         2 |       1 |
+----+-----------+-----------+---------+
3 rows in set (0.00 sec)

I need this, with the ORM, and NOT with the raw SQL query facility from the ORM to get all items that don't have a status for this member.

The SQL query at the beginning of the question does this, so it's important to have the

AND ism.member_id = 2

condition as a second condition to the left-join part, instead of moving into where, which I know how to do.


from django.db.models import Q    
Item.objects.filter(~Q(member__id=2))
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜