DRF - 过滤 2 个模型

DRF - filter across 2 models

我正在使用遗留数据库,其中我在 Table A 上设置了序列化程序,就像这样 -

class TblapplicationsSerializer(serializers.ModelSerializer):

    class Meta:
        model = Tblapplications
        fields = ('applicationid', 'applicationname', 'description', 'drtierid', 'saglink', 'supportinstructions',
                  'defaultincidentpriorityid', 'applicationorigintypeid', 'installationtypeid', 'comments',
                  'lastmodifieddate', 'lastmodifiedby', 'assetstatusid', 'recordownerid', 'adl_app')
        depth = 2

我使用的是标准过滤器 -

class TblapplicationsFilter(django_filters.FilterSet):
    name = django_filters.CharFilter(name="applicationname", lookup_type="exact")
    env = django_filters.CharFilter(name="adl_app__environmentid__domain")

    class Meta:
        model = Tblapplications
        fields = ['applicationname', 'name', 'env']

这是它横盘整理的地方。我想要做的是过滤我的 URL,比如 /api/applications/?name=xxx&env=DEV。然后它将 return 与 DEV 环境链接的应用程序和任何数据库。这个名字很容易理解,但我唯一想出的环境是让应用程序的 api 点触及链接两者的中间 table 但它 return 有多个值,因为每次使用单独的数据库引用应用程序时,它都会被抓取。

我已经根据给定的注释和序列化程序更新了序列化程序和过滤器,没有 &env=DEV return 所有适当的数据(domain 嵌套在反向关系中).然后我希望我的过滤器基于此过滤结果。这意味着它需要以某种方式知道将反向关系的结果限制为仅嵌套值提供的结果。

如果你看到我的模型 -

class Tblapplicationdatabaselinks(models.Model):
    id = models.AutoField(db_column='ID', primary_key=True)
    applicationid = models.ForeignKey('Tblapplications', db_column='applicationId', to_field='applicationid',
                                      related_name='adl_app')
    dbid = models.ForeignKey('Tbldatabases', db_column='dbId', to_field='id', related_name='adl_db')
    environmentid = models.ForeignKey('Tbldomaincodes', db_column='environmentId', to_field='id',
                                      related_name='adl_envlink')
    comments = models.TextField(blank=True)
    lastmodifieddate = models.DateTimeField(db_column='lastModifiedDate', blank=True, null=True)
    lastmodifiedby = models.CharField(db_column='lastModifiedBy', max_length=255, blank=True)
#    upsize_ts = models.TextField(blank=True) # This field type is a guess.

    class Meta:
        managed = False
        db_table = 'tblApplicationDatabaseLinks'

class Tblapplications(models.Model):
    applicationid = models.AutoField(db_column='applicationId', primary_key=True)
    applicationname = models.CharField(db_column='applicationName', max_length=255)
    description = models.TextField(blank=True)
    drtierid = models.ForeignKey(Tbldomaincodes, db_column='drTierID', blank=True, null=True, to_field='id',
                                 related_name='app_drtier')
    saglink = models.TextField(db_column='sagLink', blank=True)
    supportinstructions = models.TextField(db_column='supportInstructions', blank=True)
    defaultincidentpriorityid = models.IntegerField(db_column='defaultIncidentPriorityId', blank=True, null=True)
    applicationorigintypeid = models.IntegerField(db_column='applicationOriginTypeId')
    installationtypeid = models.ForeignKey(Tbldomaincodes, db_column='installationTypeId', to_field='id',
                                           related_name='app_insttype')
    comments = models.TextField(blank=True)
    assetstatusid = models.ForeignKey(Tbldomaincodes, db_column='assetStatusId', to_field='id',
                                      related_name='app_status')
    recordownerid = models.ForeignKey(Tblusergroups, db_column='recordOwnerId', blank=True, null=True,
                                      to_field='groupid', related_name='app_owner')
    lastmodifieddate = models.DateTimeField(db_column='lastModifiedDate', blank=True, null=True)
    lastmodifiedby = models.CharField(db_column='lastModifiedBy', max_length=255, blank=True)
#    upsize_ts = models.TextField(blank=True) # This field type is a guess.

    class Meta:
        managed = False
        db_table = 'tblApplications'

class Tbldatabases(models.Model):
    dbid = models.AutoField(db_column='dbId', primary_key=True)
    dbname = models.CharField(db_column='dbName', max_length=255)
    serverid = models.ForeignKey('Tblservers', db_column='serverId', to_field='serverid', related_name='db_serv')
    servicename = models.CharField(db_column='serviceName', max_length=255, blank=True)
    dbtypeid = models.IntegerField(db_column='dbTypeId', blank=True, null=True)
    inceptiondate = models.DateTimeField(db_column='inceptionDate', blank=True, null=True)
    comments = models.TextField(blank=True)
    assetstatusid = models.IntegerField(db_column='assetStatusId')
    recordownerid = models.IntegerField(db_column='recordOwnerId', blank=True, null=True)
    lastmodifieddate = models.DateTimeField(db_column='lastModifiedDate', blank=True, null=True)
    lastmodifiedby = models.CharField(db_column='lastModifiedBy', max_length=255, blank=True)
#    upsize_ts = models.TextField(blank=True) # This field type is a guess.

    class Meta:
        managed = False
        db_table = 'tblDatabases'

class Tbldomaincodes(models.Model):
    id = models.IntegerField(db_column='ID', primary_key=True)
    domain = models.CharField(primary_key=True, max_length=255)
    displayname = models.CharField(db_column='displayName', primary_key=True, max_length=255)
    displayorder = models.IntegerField(db_column='displayOrder', blank=True, null=True)
    comments = models.TextField(blank=True)
    lastmodifieddate = models.DateTimeField(db_column='lastModifiedDate', blank=True, null=True)
    lastmodifiedby = models.CharField(db_column='lastModifiedBy', max_length=255, blank=True)
#    upsize_ts = models.TextField(blank=True) # This field type is a guess.

    class Meta:
        managed = False
        db_table = 'tblDomainCodes'

扩展您的过滤器集并引用其他模型中的字段:

class TblapplicationsFilter(django_filters.FilterSet):
    name = django_filters.CharFilter(name="applicationname", lookup_type="exact")
    env = django_filters.CharFilter(name="environmentid__name")
    #                                    ^^^^^^^^^^^^^^^^^^^

    class Meta:
        model = Tblapplications
        fields = ['applicationname', 'name', 'env']

此外,您可能希望在命名 ForeignKey 字段时不带 id 后缀,这是 Django 的惯例。在 Django 中,当你访问 Tblapplications.environmentid 时,它通常是一个模型实例,而不是实际的 id 整数本身。