多表关系,反向筛选

该博客介绍了如何在Django中使用filterset来根据标签ID查询人员信息。通过PersonToTag中间表,实现了从标签关联到人员的查询,筛选出具有特定标签的所有人员对象。过滤器包括姓名模糊搜索和精确的地理位置及工程师级别查询。
摘要由CSDN通过智能技术生成
class PersonFilterSet(filters.FilterSet):
    name = filters.CharFilter(field_name='name', lookup_expr="icontains",
                              help_text='模糊搜索根据人员名称,name=xxx')  # icontains 包含,忽略大小写
    tag_id = filters.NumberFilter(help_text='标签ID', method='get_query_tag')

    class Meta:
        model = Person
        fields = {
            'location_county_id': ['exact'],
            'location_city_id': ['exact'],
            'location_province_id': ['exact'],
            'engineer_level': ['exact'],
        }

    def get_query_tag(self, queryset, _, value):
        if value:
            person_ids = PersonToTag.objects.filter(tag_id=value).values_list('person_id', flat=True)
            return queryset.filter(id__in=list(person_ids))
        return queryset

讲解:
在此filters里边是基于三张表的
人员表Person
标签表Tag
人与标签表的关系PersonToTag
需求:根据tag_id查询到拥有此标签的所有人
首先PersonToTag.objects.filter(tag_id=value),查询关系表中,所有有此标签人的对象,再.values_list(‘person_id’, flat=True)取出来所有的person_id字段,最终queryset.filter(id__in=list(person_ids))筛选出所有的人员对象

Django框架中,如果你需要跨关系查找数据表中的字段,通常意味着你要联合查询两个或多个相关联的模型。这里有几个步骤可以帮助你实现跨关系的数据查找: 1. 确定模型关系:首先你需要清楚你的模型之间是如何关联的。Django提供了几种关系类型,包括`ForeignKey`(一对多)、`ManyToManyField`(多对多)和`OneToOneField`(一对一)。根据你的模型设计,确定好这些关系。 2. 使用QuerySet API:Django的ORM提供了一个强大的QuerySet API,可以用来构建复杂的查询。使用`filter()`、`exclude()`、`get()`等方法可以进行数据筛选。 3. 使用跨表查询方法:Django支持几种跨表查询方法,如`select_related`和`prefetch_related`。`select_related`用于查询`ForeignKey`和`OneToOneField`类型的关系,它通过SQL的JOIN操作一次性获取相关数据,减少数据库的查询次数。`prefetch_related`用于查询`ManyToManyField`和反向外键关系,它分别查询相关表的数据,并在Python中将它们组合起来。 4. 使用F表达式和Q对象:如果你需要进行复杂的查询条件,比如比较字段与字段之间的关系,你可以使用Django的F表达式和Q对象。F表达式用于引用模型字段的值,而Q对象允许构建复杂的查询条件。 5. 使用注解(annotate)和聚合(aggregate):注解可以在查询集中添加额外的信息,比如计算子表的记录数等。聚合函数(如Sum, Max, Min等)可以用来进行统计计算。 范例代码如下: ```python from django.db.models import Count, Q # 假设有两个模型 ModelA 和 ModelB,它们之间通过 ForeignKey 关联 # 查询ModelA的所有实例,并计算每个实例关联的ModelB的数量 model_a queryset = ModelA.objects.annotate(count=Count('modelb')).all() # 使用 Q 对象进行更复杂的查询条件 # 查询ModelA中某个字段等于'某个值'的实例,或者ModelB中某个字段等于'另一个值'的实例 complex_queryset = ModelA.objects.filter(Q(field_a='some_value') | Q(modelb__field_b='another_value')) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值