1. 程式人生 > 其它 >【Django雜記】django model物件轉換成dict格式

【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