【Django杂记】django model对象转换成dict格式

在接口里我们经常遇到这种需求,需要将对象的各个字段值返回
user = User.objects.get(id=1)
第一种方法,没错,我这样写过:
user_dict = {}
user_dict['username'] = user.username
user_dict['email'] = user.email
...
第二种方法:
user_dict = {}
all_fields = User._meta.get_all_field_names()
special_fields = ['username', 'email', ...]
for i in special_fields:
    try:
        all_fields.remove(i)
    except:
        pass
for field in all_fields:
    user_dict[field] = getattr(user, field)
第三种方法:model_to_dict
看到这种命名就有一种暖暖的体贴感,有木有,一眼就知道了怎么用和返回值
from django.forms.models import model_to_dict

user_dict = model_to_dict(user, exclude=['is_active', 'is_stuff'])

# 源码
def model_to_dict(instance, fields=None, exclude=None):
   	for f in chain(opts.concrete_fields, opts.private_fields, opts.many_to_many):
        if not getattr(f, 'editable', False):
            continue

# 解析
instance: 对象实例
fields: 指定需要哪些字段
exclude: 指定排除哪些字段
    
# 注意:
excluede比fields优先级高;但是会跳过有editable=False属性字段的展示,
对于有auto_now_add=True和auto_now=True属性的datetime字段会默认添加editable=False
隐藏属性,time相关的字段转换成dict后不显示的原因。
方法四:自定义to_dict
from django.db.models.fields import DateTimeField
from django.db.models.fields.related import ManyToManyField

class User(mdoels.Model):
    ...
    def to_dict(self, fields=None, exclude=None):
        data = {}
        for f in self._meta.concrete_fields + self._meta.many_to_many:
            value = f.value_from_object(self)
			if fields and f.name not in fields:
                continue
            if exclude and f.name in exclude:
                continue
            if isinstance(f, ManyToManyField):
                value = [i.if for i in value] if self.pk else None
            if isinstance(f, DataTimeField):
                value = value.selftime('%Y-%m-%d %H:%M:%S') if value else None
             
            data[f.name] = value
            
        return data
posted @ 2022-05-31 13:58  郭祺迦  阅读(797)  评论(2)    收藏  举报