มีหลายวิธีในการแปลงอินสแตนซ์เป็นพจนานุกรมโดยมีองศาการจัดการตัวพิมพ์มุมและการใกล้เคียงกับผลลัพธ์ที่ต้องการ
1 instance.__dict__
instance.__dict__
ซึ่งผลตอบแทน
{'_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}
นี่เป็นวิธีที่ง่ายที่สุด แต่ขาดไป many_to_many , foreign_keyจะเรียกไม่ถูกและมันมีสองสิ่งพิเศษที่ไม่พึงประสงค์ในนั้น
2 model_to_dict
from django.forms.models import model_to_dict
model_to_dict(instance)
ซึ่งผลตอบแทน
{'foreign_key': 2,
 'id': 1,
 'many_to_many': [<OtherModel: OtherModel object>],
 'normal_value': 1}
นี่เป็นสิ่งเดียวเท่านั้นที่มี many_to_manyฟิลด์แต่ไม่มีฟิลด์ที่แก้ไขไม่ได้
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])
ซึ่งผลตอบแทน
{'foreign_key': 2, 'id': 1, 'normal_value': 1}
นี่แย่กว่ามาตรฐานอย่างเคร่งครัด model_to_dictเรียกใช้
4 query_set.values()
SomeModel.objects.filter(id=instance.id).values()[0]
ซึ่งผลตอบแทน
{'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}
นี่เป็นเอาต์พุตเดียวกันกับinstance.__dict__แต่ไม่มีฟิลด์เพิ่มเติม
foreign_key_idยังคงผิดและmany_to_manyยังขาดหายไป
5. ฟังก์ชั่นที่กำหนดเอง
รหัสสำหรับ django's model_to_dictมีคำตอบส่วนใหญ่ มันลบเขตข้อมูลที่ไม่สามารถแก้ไขได้อย่างชัดเจนดังนั้นการลบการตรวจสอบและการรับรหัสต่างประเทศสำหรับเขตข้อมูลจำนวนมากไปยังเขตพื้นที่ต่าง ๆ ส่งผลให้รหัสต่อไปนี้ซึ่งทำงานตามที่ต้องการ:
from itertools import chain
def to_dict(instance):
    opts = instance._meta
    data = {}
    for f in chain(opts.concrete_fields, opts.private_fields):
        data[f.name] = f.value_from_object(instance)
    for f in opts.many_to_many:
        data[f.name] = [i.id for i in f.value_from_object(instance)]
    return data
ในขณะที่นี่เป็นตัวเลือกที่ซับซ้อนที่สุดการโทรto_dict(instance)ให้ผลลัพธ์ตามที่ต้องการ:
{'auto_now_add': datetime.datetime(2018, 12, 20, 21, 34, 29, 494827, tzinfo=<UTC>),
 'foreign_key': 2,
 'id': 1,
 'many_to_many': [2],
 'normal_value': 1,
 'readonly_value': 2}
6. ใช้ Serializers
ModelSerialzer ของDjango Rest Frameworkอนุญาตให้คุณสร้าง serializer โดยอัตโนมัติจากรุ่น
from rest_framework import serializers
class SomeModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = SomeModel
        fields = "__all__"
SomeModelSerializer(instance).data
ผลตอบแทน
{'auto_now_add': '2018-12-20T21:34:29.494827Z',
 'foreign_key': 2,
 'id': 1,
 'many_to_many': [2],
 'normal_value': 1,
 'readonly_value': 2}
นี่เกือบจะดีเท่ากับฟังก์ชั่นที่กำหนดเอง แต่ auto_now_add เป็นสตริงแทนวัตถุ datetime
รอบโบนัส: การพิมพ์แบบที่ดีขึ้น
หากคุณต้องการรุ่น django ที่มีการแสดงบรรทัดคำสั่งของ python ที่ดีกว่าให้รุ่นของคุณเป็นคลาสย่อยดังต่อไปนี้:
from django.db import models
from itertools import chain
class PrintableModel(models.Model):
    def __repr__(self):
        return str(self.to_dict())
    def to_dict(instance):
        opts = instance._meta
        data = {}
        for f in chain(opts.concrete_fields, opts.private_fields):
            data[f.name] = f.value_from_object(instance)
        for f in opts.many_to_many:
            data[f.name] = [i.id for i in f.value_from_object(instance)]
        return data
    class Meta:
        abstract = True
ตัวอย่างเช่นถ้าเรากำหนดแบบจำลองของเราเช่น:
class OtherModel(PrintableModel): pass
class SomeModel(PrintableModel):
    normal_value = models.IntegerField()
    readonly_value = models.IntegerField(editable=False)
    auto_now_add = models.DateTimeField(auto_now_add=True)
    foreign_key = models.ForeignKey(OtherModel, related_name="ref1")
    many_to_many = models.ManyToManyField(OtherModel, related_name="ref2")
การโทรSomeModel.objects.first()ตอนนี้ให้เอาต์พุตดังนี้:
{'auto_now_add': datetime.datetime(2018, 12, 20, 21, 34, 29, 494827, tzinfo=<UTC>),
 'foreign_key': 2,
 'id': 1,
 'many_to_many': [2],
 'normal_value': 1,
 'readonly_value': 2}
               
              
to_dictและจัดการในแบบที่คุณต้องการ