首页 > 解决方案 > 具有反向关系的 Django 过滤器

问题描述

我正在为 API 使用 django rest 框架。并按照这里的文件。

这是一个名为“NetworkMember”的模型。

class NetworkMember(CommonInfo):
    name = models.CharField('name',max_length=255, blank=True, null=True, default=None)
    status = models.CharField(max_length=50, choices=NETWORK_STATUS_OPTS, default=None)
    network = models.ForeignKey(Network, related_name='network_members', on_delete=models.CASCADE, default=None)
    sender = models.ForeignKey(Account, related_name='sender', on_delete=models.CASCADE, default=None)
    receiver = models.ForeignKey(Account, related_name='receiver', on_delete=models.CASCADE, default=None)
    def __str__(self):
        return self.name

问题仅与“接收者”字段有关。因此,下面是相关的“帐户”模型。

class Account(CommonInfo):
    name = models.CharField(max_length=50)
    is_master_ma = models.CharField(max_length=10, choices=IS_MASTER_MA_OPTS, blank=True, null=True,default=None)
    account_type = models.CharField(max_length=50, choices=ACCOUNT_TYPE_OPTS)
    master_account = models.ForeignKey('self', related_name='masterMA',on_delete=models.CASCADE, blank=True, null=True,default=None)
    billing_account = models.ForeignKey('self', related_name='BA',on_delete=models.CASCADE, blank=True, null=True,default=None)
    def __str__(self):
        return self.name

一个 Billing 账户可以有一个主账户。同样,一个主帐户可以有多个子用户帐户。因此,“帐户”模型中有 2 个自我关系 - master_account 和 billing_account。

现在网络成员与主帐户相关。我们也有一些设备。设备与计费帐户相关。这是设备型号。

class Device(CommonInfo):
    name = models.CharField(max_length=250)
    unique_id = models.CharField(max_length=100)
    status = models.CharField(max_length=50, choices=DEV_STATUS_OPTS, blank=True, null=True, default=None)
    billing_account = models.ForeignKey(Account, related_name='ba_devices', on_delete=models.CASCADE, blank=True, null=True, default=None)
    primary = models.CharField(max_length=50, choices=DEV_PRIMARY_OPTS, blank=True, null=True, default=None)
    def __str__(self):
        return self.name

所以我需要获取具有特定名称或基于primary ='Yes'的网络成员设备。让我们先关注名称。所以流程将是 -

从网络成员 - 获取主帐户 ID - 然后获取其计费帐户 ID - 然后获取设备 - 然后使用提供的名称进行过滤。

我设法通过在views.py 中使用django 过滤器来做到这一点。

network_accepted = NetworkMember.objects.filter(network=nid, sender=uid, status="Accepted", receiver__billing_account__ba_devices__name = 'stmk')

然后导入 Q 并尝试以下操作。

network_accepted = NetworkMember.objects.filter(Q(network=nid, sender=uid, status="Accepted")).filter(Q(receiver__billing_account__ba_devices__name = 'stmk'))

network_accepted = NetworkMember.objects.filter(Q(network=nid, sender=uid, status="Accepted") & Q(receiver__billing_account__ba_devices__name = 'stmk'))

network_accepted = NetworkMember.objects.filter(Q(network=nid, sender=uid, status="Accepted") & Q(receiver__billing_account__ba_devices__name__startswith = 'stmk'))

network_accepted = NetworkMember.objects.filter( Q(receiver__billing_account__ba_devices__name__iexact = 'stmk'))

network_accepted = NetworkMember.objects.filter( Q(receiver__billing_account__ba_devices__name__startswith = 'stmk'))

只有一个名为“stmk”的设备。因此,当我执行这些过滤器时,它应该只为该特定网络成员返回一个设备。对于我的测试,我对名称进行了硬编码,但它将是动态的。但我面临的问题是,如果找到设备名称,它会返回该网络成员的所有设备。

前任。如果我使用任何其他字符串(如“随机”)进行搜索,则结果为空 - 这很好,因为没有具有该名称的设备。但是,如果我用“stmk”搜索它会返回所有设备。如何将设备列表限制为仅“stmk”设备。这是2个屏幕截图。

在此处输入图像描述

在此处输入图像描述

标签: djangodjango-rest-framework

解决方案


推荐阅读