model_to_dict datetime 不转换

2022-08-15 12:38:48 浏览数 (2)

問題:

Django model_to_dict skips all DateTimeField when converting models

原因:

  • model定义时,updated_at, created_at 添加了auto_now,auto_now_add
  • auto_nowauto_now_add设置为True,将导致该字段设置为editable=Falseblank=True

解决方案:

重写(自定义)model_to_dict

详细:

model 定义参照

代码语言:javascript复制
class BaseModel(models.Model):
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='登録日時')
    updated_at = models.DateTimeField(auto_now=True, verbose_name='更新日時')

django自带model_to_dict定义参照

代码语言:python代码运行次数:0复制
# 调用时导入
from django.forms.models import model_to_dict

# 定义参照
def model_to_dict(instance, fields=None, exclude=None):
    """
    Return a dict containing the data in ``instance`` suitable for passing as
    a Form's ``initial`` keyword argument.

    ``fields`` is an optional list of field names. If provided, return only the
    named.

    ``exclude`` is an optional list of field names. If provided, exclude the
    named from the returned dict, even if they are listed in the ``fields``
    argument.
    """
    opts = instance._meta
    data = {}
    for f in chain(opts.concrete_fields, opts.private_fields, opts.many_to_many):
        if not getattr(f, 'editable', False):   # 这里导致updated_at被跳过
            continue
        if fields is not None and f.name not in fields:
            continue
        if exclude and f.name in exclude:
            continue
        data[f.name] = f.value_from_object(instance)
    return data

重写model_to_dict,(或者别名)自定义方法

注:若重写该方法,调用时,要import自定义的方法。

代码语言:python代码运行次数:0复制
# 重写 model_to_dict
# 形参添加 has_editable,默认True
# 调用时:from .util.convert import model_to_dict

>pj>util>convert.py
    
def model_to_dict(instance, fields=None, exclude=None, has_editable=True):
    '''
        model to dict。

        Args: 
            instance: model
            fields: プロパティを指定する
            exclude: プロパティを除外する
            has_editable: 自動更新も含めて処理する
        return: 
            dict
    '''
    opts = instance._meta
    
    data = {}
    for f in chain(opts.concrete_fields, opts.private_fields, opts.many_to_many):
        if not has_editable and not getattr(f, "editable", False):
            # 若不处理自己动更新字段,则跳过
            continue
        if fields is not None and f.name not in fields:
            continue
        if exclude and f.name in exclude:
            continue
        data[f.name] = f.value_from_object(instance)
    return data

0 人点赞