एक मामले को डिक्शनरी में बदलने के कई तरीके हैं, जिसमें कोने केस हैंडलिंग की अलग-अलग डिग्री और वांछित परिणाम के लिए निकटता है।
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 के कोड का 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. सीरियल का उपयोग करें
Django रेस्ट फ्रेमवर्क 'ModelSerialzer आपको एक मॉडल से स्वचालित रूप से एक धारावाहिक बनाने की अनुमति देता है।
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}
यह लगभग कस्टम फ़ंक्शन के रूप में अच्छा है, लेकिन ऑटो_नो_डैट एक डेटाइम ऑब्जेक्ट के बजाय एक स्ट्रिंग है।
बोनस दौर: बेहतर मॉडल प्रिंटिंग
यदि आप एक django मॉडल चाहते हैं जिसमें एक बेहतर अजगर कमांड-लाइन डिस्प्ले है, तो अपने मॉडल को निम्न में से चाइल्ड-क्लास करें:
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और इसे जिस तरह से आप चाहते हैं उसे संभाल सकते हैं।