将Django Model对象转换为所有字段完整的dict [英] Convert Django Model object to dict with all of the fields intact

查看:2974
本文介绍了将Django Model对象转换为所有字段完整的dict的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何将django Model对象转换为其字段中全部的dict?所有理想情况下都包括外键和可编辑= False的字段。



让我详细说明一下。假设我有一个django模型,如下所示:

 从django.db导入模型

类OtherModel(models.Model):pass

class SomeModel(models.Model):
value = models.IntegerField()
value2 = models.IntegerField(editable = False)
created = models.DateTimeField(auto_now_add = True)
reference1 = models.ForeignKey(OtherModel,related_name =ref1)
reference2 = models.ManyToManyField(OtherModel,related_name =ref2)

在终端中,我已经完成了以下操作:

  other_model = OtherModel()
other_model.save()
instance = SomeModel()
instance.value = 1
实例。 value2 = 2
instance.reference1 = other_model
instance.save()
instance.reference2.add(other_model)
instance.save()

我想将其转换为以下字典:

 code> {'created':datetime.dat etime(2015,3,16,21,34,14,926738,tzinfo =< UTC),
u'id':1,
'reference1':1,
' reference2':[1],
'value':1,
'value2':2}






不满意答案的问题:



Django:将整套Model对象转换为单个字典



我如何将Django Model对象转换成字典并仍然拥有外键?

解决方案

有许多方法可以将实例转换为字典,具有不同程度的角位处理和逼近所需的结果。






1。 实例.__ dict __



 实例.__ dict__ 







$ b pre $ < _reference1_cache':< OtherModel:OtherModel object>
'_state':< django.db.models.base.ModelState at 0x1f63310>
'created':datetime.datetime(2014,2, ,
'id':1L,
'reference1_id':1L,
'value':1,
'value2':2}

这是迄今为止最简单的,但是缺少reference2,reference1没有名字,它有两个额外的东西。






2。 import_to_dict
model_to_dict(instance)
$ b $ $ $ $ $ $ $ $ c>

其中返回

  {u'id ':1L,'reference1':1L,'reference2':[1L],'value':1} 

这是唯一具有reference2的内容,但是缺少不可编辑的字段。






3。 model_to_dict with fields



  from django.forms.models import model_to_dict 
model_to_dict(instance,fields = [field.name for字段in instance._meta.fields])

其中返回

  {u'id':1L,'reference1':1L,'value':1} 

这比标准的model_to_dict调用严格得多。






4 。 query_set.values()



  SomeModel.objects.filter(id = instance.id).values()[0] 

其中返回

  {'created':datetime.datetime(2014,2,21,4,38,51,tzinfo =< UTC),
u'id':1L,
'reference1_id' :1L,
'value':1L,
'value2':2L}

这是与实例相同的输出.__ dict __ 但没有额外的字段。






5。自定义函数



django的model_to_dict的代码有很多答案。它显式删除不可编辑的字段,因此删除该检查会导致以下代码,其行为如下:

  from django.db .models.fields.related import ManyToManyField 

def to_dict(instance):
opts = instance._meta
data = {}
for opt in opts.concrete_fields + opts.many_to_many:
如果isinstance(f,ManyToManyField):
如果instance.pk是None:
data [f.name] = []
else:
data [f.name] = list(f.value_from_object(instance).values_list('pk',flat = True))
else:
data [f.name] = f.value_from_object(instance)
返回数据

虽然这是最复杂的选项,但调用 to_dict(instance)给我们准确的结果:

  {'created':datetime.datetime (2015,3,16,21,34,14,926738,tzinfo =< UTC),
u'id':1,
'reference1':1,
'reference2':[1],
'value':1,
'value2':2}






奖金回合



如果你想要一个具有更好的python命令行显示的django模型,让你的模型子类如下:

  from django.db导入模型
from django.db.models.fields.related import ManyToManyField

class PrintableModel(models.Model):
def __repr __(self):
return str (self.to_dict())

def to_dict(self):
opts = self._meta
data = {}
for opt in cons.concrete_fields + opts .many_to_many:
如果isinstance(f,ManyToManyField):
如果self.pk为无:
data [f.name] = []
else:
数据[f.name] = list(f.value_from_object(self).values_list('pk',flat = True))
else:
data [f.name] = f.value_from_object(self)
返回数据

class Meta:
abstract = True
pre>

所以,例如,如果我们定义我们的模型:

  class OtherModel(PrintableModel):pass 

class SomeModel(PrintableModel):
value = models.IntegerField()
value2 = models.IntegerField(editable = False)
created = models.DateTimeField(auto_now_add = True)
reference1 = models.ForeignKey(OtherModel,related_name =ref1)
reference2 = models.ManyToManyField(OtherModel,related_name =ref2)

现在调用 SomeModel.objects.first()给出这样的输出:

  {'created':datetime.datetime(2015,3,16,21,34, 926738,tzinfo =< UTC),
'value':1,'value2':2,'reference1':1,u'id':1,'reference2':[1]}


How does one convert a django Model object to a dict with all of its fields? All ideally includes foreign keys and fields with editable=False.

Let me elaborate. Let's say I have a django model like the following:

from django.db import models

class OtherModel(models.Model): pass

class SomeModel(models.Model):
    value = models.IntegerField()
    value2 = models.IntegerField(editable=False)
    created = models.DateTimeField(auto_now_add=True)
    reference1 = models.ForeignKey(OtherModel, related_name="ref1")
    reference2 = models.ManyToManyField(OtherModel, related_name="ref2")

In the terminal, I have done the following:

other_model = OtherModel()
other_model.save()
instance = SomeModel()
instance.value = 1
instance.value2 = 2
instance.reference1 = other_model
instance.save()
instance.reference2.add(other_model)
instance.save()

I want to convert this to the following dictionary:

{'created': datetime.datetime(2015, 3, 16, 21, 34, 14, 926738, tzinfo=<UTC>),
 u'id': 1,
 'reference1': 1,
 'reference2': [1],
 'value': 1,
 'value2': 2}


Questions with unsatisfactory answers:

Django: Converting an entire set of a Model's objects into a single dictionary

How can I turn Django Model objects into a dictionary and still have their foreign keys?

解决方案

There are many ways to convert instance to a dictionary, with varying degrees of corner case handling and closeness to the desired result.


1. instance.__dict__

instance.__dict__

which returns

{'_reference1_cache': <OtherModel: OtherModel object>,
 '_state': <django.db.models.base.ModelState at 0x1f63310>,
 'created': datetime.datetime(2014, 2, 21, 4, 38, 51, 844795, tzinfo=<UTC>),
 'id': 1L,
 'reference1_id': 1L,
 'value': 1,
 'value2': 2}

This is by far the simplest, but is missing reference2, reference1 is misnamed, and it has two extra things in it.


2. model_to_dict

from django.forms.models import model_to_dict
model_to_dict(instance)

which returns

{u'id': 1L, 'reference1': 1L, 'reference2': [1L], 'value': 1}

This is the only one with reference2, but is missing the uneditable fields.


3. model_to_dict with fields

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

which returns

{u'id': 1L, 'reference1': 1L, '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

{'created': datetime.datetime(2014, 2, 21, 4, 38, 51, tzinfo=<UTC>),
 u'id': 1L,
 'reference1_id': 1L,
 'value': 1L,
 'value2': 2L}

This is the same output as instance.__dict__ but without the extra fields.


5. Custom Function

The code for django's model_to_dict had most of the answer. It explicitly removed non-editable fields, so removing that check results in the following code which behaves as desired:

from django.db.models.fields.related import ManyToManyField

def to_dict(instance):
    opts = instance._meta
    data = {}
    for f in opts.concrete_fields + opts.many_to_many:
        if isinstance(f, ManyToManyField):
            if instance.pk is None:
                data[f.name] = []
            else:
                data[f.name] = list(f.value_from_object(instance).values_list('pk', flat=True))
        else:
            data[f.name] = f.value_from_object(instance)
    return data

While this is the most complicated option, calling to_dict(instance) gives us exactly the desired result:

{'created': datetime.datetime(2015, 3, 16, 21, 34, 14, 926738, tzinfo=<UTC>),
 u'id': 1,
 'reference1': 1,
 'reference2': [1],
 'value': 1,
 'value2': 2}


Bonus Round

If you want a django model that has a better python command-line display, have your models child class the following:

from django.db import models
from django.db.models.fields.related import ManyToManyField

class PrintableModel(models.Model):
    def __repr__(self):
        return str(self.to_dict())

    def to_dict(self):
        opts = self._meta
        data = {}
        for f in opts.concrete_fields + opts.many_to_many:
            if isinstance(f, ManyToManyField):
                if self.pk is None:
                    data[f.name] = []
                else:
                    data[f.name] = list(f.value_from_object(self).values_list('pk', flat=True))
            else:
                data[f.name] = f.value_from_object(self)
        return data

    class Meta:
        abstract = True

So, for example, if we define our models as such:

class OtherModel(PrintableModel): pass

class SomeModel(PrintableModel):
    value = models.IntegerField()
    value2 = models.IntegerField(editable=False)
    created = models.DateTimeField(auto_now_add=True)
    reference1 = models.ForeignKey(OtherModel, related_name="ref1")
    reference2 = models.ManyToManyField(OtherModel, related_name="ref2")

Calling SomeModel.objects.first() now gives output like this:

{'created': datetime.datetime(2015, 3, 16, 21, 34, 14, 926738, tzinfo=<UTC>),
'value': 1, 'value2': 2, 'reference1': 1, u'id': 1, 'reference2': [1]}

这篇关于将Django Model对象转换为所有字段完整的dict的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆