【问题标题】:Django doesn't understand if my field in the database is emptyDjango 不明白我在数据库中的字段是否为空
【发布时间】:2019-09-18 04:23:11
【问题描述】:

所以我正在开发一个 API。一个 GET 请求,它具有生成渲染一个字段或另一个字段的条件。但令我惊讶的是,is None 不适用于空字段。我该如何解决这个问题?

这是我的表格示例

--------------------------------------------------------------------------
| ms        | offer_id  | priprity_one  | priority_two  |  priority_three
--------------------------------------------------------------------------
| 89899     |           | priority_one  | priority_two  |  priority_three
| 32323     | 3021      | priority_one  | priority_two  |  priority_three
| 12321     | 3022      | priority_one  | priority_two  |  priority_three
| 43421     | 3023      | priority_one  | priority_two  |  priority_three

views.py

from mamo.models import Mamo
from rest_framework import generics
from mamo.serializers import MamoSerializer
from django.http import Http404
from IPython import embed


class OfferView(generics.ListAPIView):
    serializer_class = MamoSerializer
    lookup_field = 'ms'

    def get_queryset(self):
        msisdn = self.kwargs['ms']
        try:
            return Mamo.objects.filter(ms=ms)
        except Mamo.DoesNotExist:
            raise Http404

    def get(self, request, *args, **kwargs):
        queryset = self.get_queryset()

        serializer = self.serializer_class(queryset, many=True)

        if serializer.data[0]['offer_id'] is not None:
            result = serializer.data[0]['priority_one']
        elif serializer.data[0]['offer_id'] is None: # This line dont work
            result = serializer.data[0]['priority_two']
        else:
            result = serializer.data[0]['priority_three']
        return Response(result)

models.py

class Basic(models.Model):
    ms = models.BigIntegerField(db_index=True, blank=False, help_text="Customer")
    offer_id = models.CharField(max_length=20, null=True, blank=True)
    priority_one = models.CharField(max_length=350, null=True, blank=True, default='cleaner')
    priority_two = models.CharField(max_length=350, null=True, blank=True, default='cleaner')
    priority_three = models.CharField(max_length=350, null=False, default='cleaner') 

    class Meta:
        #ordering = ('ms',)
        db_table = 'offer_table'

    def __str__(self):
        return self.ms

为了使它起作用,这是我在下面所做的,但我认为这没有意义。我会更喜欢任何其他方式。

    if len(serializer.data[0]['offer_id']) > 0:
        result = serializer.data[0]['eligible_offer']
    elif len(serializer.data[0]['offer_id']) == 0:
        result = serializer.data[0]['market_offer']
    else:
        result = serializer.data[0]['informational_offer'] 
    return Response(result)

注意 我正在使用 DRF。我还打电话给is empty 那个不起作用的部分,它仍然不起作用。 数据库中字段为空时的意思,如我在数据库中显示的那样elif serializer.data[0]['offer_id'] is None 条件部分应该生效但没有响应

我使用embed 调试它,这是我得到的:

n [11]: serializer.data[0]['offer_id']
Out[11]: u''

In [12]: serializer.data[0]['offer_id'] is None
Out[12]: False

In [13]:  serializer.data[0]['offer_id'] is empty
Out[13]: False

【问题讨论】:

  • 首先,展示你的模型。其次,解释“不起作用”是什么意思; 究竟发生了什么?
  • 另外,如果你只想返回一个字段,你为什么要使用序列化器呢?
  • 为什么你认为该字段为 NULL?
  • 您不应在CharField 上使用null=True。默认情况下,CharField 将是空字符串,而不是 null。您必须将其显式设置为 null 才能以这种方式保存。如果未设置,它将作为 '' 保存到数据库中。这将为您提供两个可能的空值:'' 和 NULL。只需检查空字符串而不是 is None 并从模型定义中删除 null=True。
  • 另外,因为看起来offer_id 总是一个整数,所以使用可以为空的IntegerField。在这种情况下,不设置它意味着NULL将被保存,您将能够检查is None

标签: django python-2.7 django-rest-framework


【解决方案1】:

这一切都很混乱。

您的基本问题是该字段包含一个空字符串,而不是 NULL 值。那些不一样。如果您使用 Pythonic if serializer.data[0]['offer_id'] 而不是明确地与 None 进行比较,那么这将起作用。在任何情况下,您都不应该在 CharFields 上允许 null=True

您更大的问题是您完全混淆了 DRF 中的各种组件。 ListAPIView 用于返回项目列表,其get 方法与显示该列表有关。该列表应包含序列化的查询集。出于某种原因,您使用它来返回单个项目的单个字段 - 数据库中的第一个字段。这没有任何意义。

另外,序列化器用于将序列化后的数据返回给用户。无论出于何种原因,您都不想这样做,您想返回一个字段。因此,没有理由在这里使用序列化程序。您应该只检查模型的值。所以:

item = self.get_queryset().first()

if item.offer_id:
   result = item.priority_one
 ...

【讨论】:

  • 但这不是使用.first 对响应进行硬编码。不要忘记我正在使用 filter() 从数据库中选择匹配项。 Offer_id 可以在数据库中的任何位置为空
  • 另外,我相信使用 DRF 的 ListAPIView 也可以帮助您仅列出单个项目而不是所有列表(如果正确)?
  • 我不明白你在说什么。这正是您在原始代码中使用serializer.data[0] 所做的。不,如果你想要一个项目,你应该使用RetrieveAPIView' 或包含 RetrieveModelMixin 的其他视图之一。
  • 好的。谢谢。我将使用RetrieveAPIView。谢谢通知我这个错误。
猜你喜欢
  • 2014-04-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多