近期数据工作的知识点总结(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()
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.