You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于布尔字段is_active筛选Booking数据失败的技术求助

解决Django中筛选is_active=True的Booking数据问题

我正在开发一个包含表单填写的项目,表单内设有is_active布尔字段:选择True代表账户激活,选择False则账户失效且用户无法查看。尝试筛选仅展示is_active为True的Booking表单数据,但未能成功。

我的视图代码:

class BookingViewSet(viewsets.ModelViewSet): 
    serializer_class = BookingSerializer
    #queryset = Booking.objects.all()
    #queryset = Booking.objects.filter(is_active="True")
    #filter_backends = (filters.DjangoFilterBackend,)
    #filterset_class = BookingFilter
    #filterset_fields = ['is_active']


    def get_queryset(self):
        queryset = Booking.objects.all()
        username = self.request.query_params.get('bookings')
        if username is not None:
            queryset = queryset.filter(is_active__username=username)
        return queryset

我的模型代码:

class Booking(models.Model):
    booking_id = models.AutoField(primary_key=True)
    account = models.ForeignKey(Account, models.DO_NOTHING)
    tenant = models.ForeignKey(Tenant, models.DO_NOTHING)
    full_name = models.CharField(max_length=128)
    email = models.CharField(max_length=256)
    phone = models.CharField(max_length=256)
    postal_code = models.CharField(max_length=64, null=True, blank=True)
    from_city = models.CharField(max_length=256, null=True, blank=True)
    to_city = models.CharField(max_length=256, null=True, blank=True)
    travel_date = models.DateField()
    travel_period = models.CharField(max_length=256, null=True, blank=True)
    adults_travelers_count = models.SmallIntegerField()
    children_travelers_count = models.SmallIntegerField()
    senior_travelers_count = models.SmallIntegerField()
    booking_request_description = models.TextField(blank=True, null=True)
    booking_status_cd = models.CharField(max_length=10, null=True, blank=True)
    locator_code = models.CharField(max_length=32, null=True, blank=True)
    total_booking_price_atm = models.DecimalField(max_digits=11, decimal_places=2)
    total_booking_cost_atm = models.DecimalField(max_digits=11, decimal_places=2)
    payment_type_cd = models.CharField(max_length=10, null=True, blank=True)
    payment_status_cd = models.CharField(max_length=10, null=True, blank=True)
    payment_datetime = models.DateTimeField(blank=True, null=True)
    discount_percent = models.DecimalField(max_digits=3, decimal_places=1)
    discount_amount = models.DecimalField(max_digits=12, decimal_places=2)
    payment_amount = models.DecimalField(max_digits=12, decimal_places=2)
    voucher_file_path = models.TextField(blank=True, null=True)
    receipt_file_path = models.TextField(blank=True, null=True)
    invoice_file_path = models.TextField(blank=True, null=True)
    modified_ts = models.DateTimeField()
    modified_by = models.CharField(max_length=31)
    modified_op = models.CharField(max_length=1)
    created_by = models.CharField(max_length=31)
    created_ts = models.DateTimeField()
    is_active = models.BooleanField()

    class Meta:
        managed = True
        db_table = 'booking'
        unique_together = (("booking_id", "account", "tenant"),)

问题分析

  1. 注释的queryset = Booking.objects.filter(is_active="True")错误使用字符串"True",布尔字段需传入布尔值True。
  2. get_queryset中的queryset.filter(is_active__username=username)逻辑错误:is_active是布尔字段,不存在username属性,你实际应该是通过关联的Account模型用户名筛选,需改为account__username。
  3. 当前get_queryset默认返回所有记录,未添加is_active=True的过滤条件。

解决方案

方案1:修改get_queryset实现默认过滤

直接在方法中默认筛选激活状态的记录,同时修正用户名筛选逻辑:

class BookingViewSet(viewsets.ModelViewSet): 
    serializer_class = BookingSerializer

    def get_queryset(self):
        # 默认只返回激活状态的Booking记录
        queryset = Booking.objects.filter(is_active=True)
        username = self.request.query_params.get('bookings')
        if username is not None:
            # 通过关联的Account模型用户名筛选
            queryset = queryset.filter(account__username=username)
        return queryset

方案2:结合DjangoFilterBackend(可选)

如果需要支持通过查询参数动态控制过滤(比如临时查看失效记录),可启用过滤后端并保留默认过滤:

class BookingViewSet(viewsets.ModelViewSet): 
    serializer_class = BookingSerializer
    # 默认返回激活状态的记录
    queryset = Booking.objects.filter(is_active=True)
    filter_backends = (filters.DjangoFilterBackend,)
    # 允许通过?is_active=xxx参数过滤
    filterset_fields = ['is_active']

额外检查

确保数据库中is_active字段存储的是布尔值(True/False),而非字符串类型,避免类型不匹配导致过滤失效。

内容的提问来源于stack exchange,提问作者Ivan Campelo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 03:15:35