Django 视图代码有奇怪的行为

Posted

技术标签:

【中文标题】Django 视图代码有奇怪的行为【英文标题】:Django view code has weird behaviour 【发布时间】:2016-03-22 02:08:23 【问题描述】:

我写了这个 Django 视图方法:

def list_all_devices(request):

    all_devices_info = []
    fields = Devices.objects.all()
    for field in fields:
        device = Devices.objects.filter(device_id=field.device_id).values()
        dev = device[0]

        dev['variables'] = Variables.objects.filter(device_id=field.device_id).values()

        del dev['device_creation_datetime']
        all_devices_info.append(dev)

    return HttpResponse(json.dumps(all_devices_info), content_type="application/json")

由于某种原因,第一个代码不起作用,但如果我进行如下的小修改,它就会开始工作,我不知道为什么。

def list_all_devices(request):

    all_devices_info = []
    fields = Devices.objects.all()
    for field in fields:
        device = Devices.objects.filter(device_id=field.device_id).values()
        dev = device[0]

        dev['variables'] = [v for v in Variables.objects.filter(device_id=field.device_id).values()]

        del dev['device_creation_datetime']
        all_devices_info.append(dev)

    return HttpResponse(json.dumps(all_devices_info), content_type="application/json")

当我分析修改时:

[v for v in Variables.objects.filter(device_id=field.device_id).values()]

Variables.objects.filter(device_id=field.device_id).values()

它们看起来很相似,而且两者似乎都是列表,并且内部具有相同的信息。但是当通过它调用json.dumps 方法时,在第一个代码中它会在浏览器上抛出以下错误。

【问题讨论】:

你是对的:这两个表达式都给你一个列表,但两个列表非常不同。正如下面的答案所指出的,[v for v ...] 为您提供了一个 normal Python 列表,而 Variable...values() 表达式提供了一个 Django 查询字典,它也是一个列表,但具有一些额外的方法和属性。 看到这个问题:<Django object > is not JSON serializable. 【参考方案1】:

Devices.objects.filter(device_id=field.device_id).values() 是 ValuesQuerySet 派生自 QuerySet 并且两者都是 unevaluated 这意味着这是一个查询但尚未在数据库上执行直到您应用列表或对其进行迭代。 当您使用json.dumps 时,您需要数据而不是查询。

应用以下查看类型:

Devices.objects.filter(device_id=field.device_id).values().__class__

django.db.models.query.ValuesQuerySet

Devices.objects.filter(device_id=field.device_id).values().__class__.__base__

django.db.models.query.QuerySet

【讨论】:

【参考方案2】:

values() 不返回简单的数据类型。

我尝试使用 django 模型:

dir(myModel.objects.all().values())

['and', 'bool', 'class', 'deepcopy', 'delattr', 'dict', 'doc', 'format', 'getattribute', 'getitem', 'getstate', 'hash', 'init', 'iter', 'len', 'module', 'new', 'nonzero ', 'or', 'reduce', 'reduce_ex', 'repr', ' setattr', 'setstate', 'sizeof', 'str', 'subclasshook' ,'weakref','_add_hints','_as_sql','_base_queryset_class','_batched_insert','_clone','_create_object_from_params','_db','_earliest_or_latest','_extract_model_params','_fetch_all ','_fields','_filter_or_exclude','_for_write','_has_filters','_hint s','_insert','_known_related_objects','_merge_known_related_objects','_merge_sanity_check','_next_is_sticky','_populate_pk_values','_prefetch_done','_prefetch_related_lookups','_prefetch_related_objects','_prepare','_raw_delete','_res , '_setup_aggregate_query', '_setup_query', '_specialized_queryset_class', '_sticky_filter', '_update', 'aggregate', 'all', 'annotate', 'annotation_names', 'as_manager', 'bulk_create', 'complex_filter', '计数”、“创建”、“日期”、“日期时间”、“数据库”、“延迟”、“删除”、“不同”、“最早”、“排除”、“存在”、“额外”、“额外名称” , 'field_names', 'filter', 'first', 'get', 'get_or_create', 'in_bulk', 'is_compatible_query_object_type', 'iterator', 'last', 'latest', 'model', 'none', ' only'、'order_by'、'ordered'、'prefetch_related'、'query'、'raw'、'reverse'、'select_for_update'、'select_related'、'update'、'update_or_create'、'using'、'value_annotation' , '值', 'values_list']

这是一个 python 数组的目录:

dir([])

['添加', '', '包含', 'delattr', 'delitem', 'delslice', 'doc', 'eq', 'format', 'ge', 'getattribute', 'getitem', 'getslice', 'gt', 'hash', 'iadd', 'imul', 'init ', 'iter', 'le', 'len', 'lt', ' mul', 'ne', 'new', 'reduce', 'reduce_ex' , 'repr', 'reversed', 'rmul', 'setattr', 'setitem ', 'setslice', 'sizeof', 'str', 'subclasshook', '追加','计数','扩展','索引','插入','po p','删除','反向','排序']

【讨论】:

以上是关于Django 视图代码有奇怪的行为的主要内容,如果未能解决你的问题,请参考以下文章

django注释奇怪的行为(按model.id分组)

添加子视图时iOS奇怪的键盘隐藏行为

视图的奇怪行为

UIScrollView:内部视图不合适,奇怪的行为,视图在触摸时重新恢复

使用自动布局的 IB_DESIGNABLE 自定义视图的错位视图警告和奇怪行为

在 viewDidLoad 中添加子视图有奇怪的行为 [重复]