近期数据工作的知识点总结(model-dict高级用法)

一、dict存入model instance

data_dict是{}字典数值

# create instance of model
 m = MyModel(**data_dict)
# don't forget to save to database!
m.save()# create instance of model
 m = MyModel(**data_dict)
# don't forget to save to database!
m.save()

如果数据库还有特定的列,extra, extra2,不在字典里,可以单独添加,**dict必须放在最后

m2 =MyModel(extra='hello', extra2='world', **data_dict)
m2.save()

二、itertools模块 islice的用法

 islice(iterable, [start, ] stop [, step]):

创建一个迭代器: iterable[start : stop : step],跳过前start个项,迭代在stop所指定的位置停止,step指定用于跳过项的步幅。迭代默认将从0开始,步幅默认1

 后面1个数字:stop   
2个数字:start,stop
 
    a = [1, 2, 3, 4, 5, 6, 7, 8, 9]
    #iter()生成迭代器,那么islice会自然增长
    a_ite = iter(a)
    a=list(islice(a_ite,0,3))
    print(a)
    a=list(islice(a_ite,0,3))
    print(a)

输出:可以看出自动增长了

[1, 2, 3]
[4, 5, 6]

    #如果没有iter,那么对list或queryset,islice时,不会自动增长
    a = [1, 2, 3, 4, 5, 6, 7, 8, 9]
    print(list(islice(a,0,3)))
    print(list(islice(a,0,3)))

输出:可以看到,没有自动增长,取决于是否是迭代器

[1, 2, 3]
[1, 2, 3]

看这个例子,和输出,能明白用法特点

    a = range(5)
    print(a)   #range(0, 5)
    i = iter(a)
    print(i)   <range_iterator object at 0x7fd321a37330>
    print(list(islice(i, 0, 2))) #[0, 1]
print(list(islice(i, 0, 2)))   #[2, 3]

    i=list(a)
    print(i) #[0, 1, 2, 3, 4]
    print(list(islice(i, 0, 2)))#[0, 1]
    print(list(islice(i, 0, 2)))#[0, 1]

 三、把model或list转换成dict

 共3中方法

    #方法1,用dict(list(set))
   from django.contrib.auth.models import User datalist = [(user.id, user.username) for user in User.objects.all()] print(datalist)           #[(1, 'lxg1'), (2, 'lxg2'), (3, 'lxg3')] dictdata = dict(datalist) print(dictdata)          #{1: 'lxg1', 2: 'lxg2', 3: 'lxg3'} print(dictdata.get(4,'xxx')) #根据key取value,key不存在返回xxx
#
方法2,用dict(zip(2个list))
    c_value = ['blue', 'red', 'yellow']
    c_key = ['1', '2', '3']

    value_dict = dict(zip(c_key, c_value))
    print(value_dict)         #{'1': 'blue', '2': 'red', '3': 'yellow'}
    name_to_value_dict = {key:value for key, value in zip(c_key, c_value)}
    print(name_to_value_dict)    #{'1': 'blue', '2': 'red', '3': 'yellow'}

  
#控制一下逻辑,判断key的重复
c_value = ['blue', 'red', 'yellow'] c_key = ['1', '2', '3'] name_value_tuples = zip(c_key, c_value) name_to_value_dict = {} for key, value in name_value_tuples: if key in name_to_value_dict: pass # Insert logic for handling duplicate keys else: name_to_value_dict[key] = value print(name_to_value_dict) #{'1': 'blue', '2': 'red', '3': 'yellow'}
四、如何把model 变成dict

有以下方法

1. instance.__dict__
instance.__dict__ which returns

{'_foreign_key_cache': <OtherModel: OtherModel object>,
 '_state': <django.db.models.base.ModelState at 0x7ff0993f6908>,
 'auto_now_add': datetime.datetime(2018, 12, 20, 21, 34, 29, 494827, tzinfo=<UTC>),
 'foreign_key_id': 2,
 'id': 1,
 'normal_value': 1,
 'readonly_value': 2}
This is by far the simplest, but is missing many_to_many, foreign_key is misnamed, and it has two unwanted extra things in it.

2. model_to_dict
from django.forms.models import model_to_dict
model_to_dict(instance) which returns:

{'foreign_key': 2,
 'id': 1,
 'many_to_many': [<OtherModel: OtherModel object>],
 'normal_value': 1}
This is the only one with many_to_many, but is missing the uneditable fields.

3. model_to_dict(..., fields=...)
from django.forms.models import model_to_dict
model_to_dict(instance, fields=[field.name for field in instance._meta.fields]) which returns:

{'foreign_key': 2, 'id': 1, 'normal_value': 1}
This is strictly worse than the standard model_to_dict invocation.

4. query_set.values()
SomeModel.objects.filter(id=instance.id).values()[0] which returns:

{'auto_now_add': datetime.datetime(2018, 12, 20, 21, 34, 29, 494827, tzinfo=<UTC>),
 'foreign_key_id': 2,
 'id': 1,
 'normal_value': 1,
 'readonly_value': 2}
This is the same output as instance.__dict__ but without the extra fields. foreign_key_id is still wrong and many_to_many is still missing.

5. Use Serializers
Django Rest Framework's ModelSerialzer allows you to build a serializer automatically from a model.

from rest_framework import serializers
class SomeModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = SomeModel
        fields = "__all__"

SomeModelSerializer(instance).data
returns

{'auto_now_add': '2018-12-20T21:34:29.494827Z',
 'foreign_key': 2,
 'id': 1,
 'many_to_many': [2],
 'normal_value': 1,
 'readonly_value': 2}
This is almost as good as the custom function, but auto_now_add is a string instead of a datetime object.
原文地址:https://www.cnblogs.com/lxgbky/p/15048099.html