python - تحويل كائن Django Model إلى dict مع كافة الحقول سليمة




dictionary django-models (6)

(لم أقصد التعليق)

حسنًا ، لا يعتمد في الواقع على الأنواع بهذه الطريقة. ربما أكون قد فهمت السؤال الأصلي هنا ، لذا أسامحني إذا كان هذا هو الحال. إذا قمت بإنشاء serliazers.py ثم هناك يمكنك إنشاء فئات تحتوي على فئات التعريف.

Class MyModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = modelName
        fields =('csv','of','fields')

ثم عندما تحصل على البيانات في فئة العرض ، يمكنك:

model_data - Model.objects.filter(...)
serializer = MyModelSerializer(model_data, many=True)
return Response({'data': serilaizer.data}, status=status.HTTP_200_OK)

هذا إلى حد كبير ما لدي في varity من الأماكن ويعود JSON لطيفة عبر JSONRenderer.

كما قلت هذا هو مجاملة من DjangoRestFramework لذلك يستحق النظر في ذلك.

كيف يقوم أحد بتحويل كائن نموذج django إلى dict مع كافة الحقول الخاصة به؟ جميع من الناحية المثالية تتضمن مفاتيح وحقول أجنبية مع editable = False.

اسمحوا لي أن أتوسع. لنفترض أن لدي نموذج django مثل ما يلي:

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")

في المحطة ، قمت بما يلي:

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()

أرغب في تحويل هذا إلى القاموس التالي:

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

أسئلة مع إجابات غير مرضية:

Django: تحويل مجموعة كاملة من كائنات النموذج إلى قاموس واحد

كيف يمكنني تحويل كائنات Django Model إلى قاموس ومازال لدينا مفاتيح خارجية؟


أبسط طريقة ،

  1. إذا كان الاستعلام الخاص بك هو Model.Objects.get ():

    سيعود get () إلى مثيل واحد بحيث يمكنك توجيه الاستخدام __dict__ من المثيل الخاص بك

    model_dict = Model.Objects.get().__dict__

  2. للفلتر () / جميع ():

    سيعرض all () / filter () قائمة بالمثيلات حتى يمكنك استخدام values() للحصول على قائمة الكائنات.

    model_values ​​= قيم Model.Objects.all (). ()


الكثير من الحلول المثيرة للاهتمام هنا. كان حيل لإضافة أسلوب as_dict إلى النموذج الخاص بي مع فهم dict.

def as_dict(self):
    return dict((f.name, getattr(self, f.name)) for f in self._meta.fields)

كمكافأة ، فإن هذا الحل المقترن بفهم قائمة على استعلام يجعل الحل لطيفًا إذا كنت تريد تصدير النماذج الخاصة بك إلى مكتبة أخرى. على سبيل المثال ، إغراق النماذج الخاصة بك في dataframe الباندا:

pandas_awesomeness = pd.DataFrame([m.as_dict() for m in SomeModel.objects.all()])

ربما هذا يساعدك. قد لا يختص هذا بالعديد من الروايات ، ولكنه مفيد للغاية عندما تريد إرسال نموذجك بصيغة json.

def serial_model(modelobj):
  opts = modelobj._meta.fields
  modeldict = model_to_dict(modelobj)
  for m in opts:
    if m.is_relation:
        foreignkey = getattr(modelobj, m.name)
        if foreignkey:
            try:
                modeldict[m.name] = serial_model(foreignkey)
            except:
                pass
  return modeldict

كانZags الحل رائع!

وأود أن أضيف ، على الرغم من ذلك ، شرط ل historyfields من أجل جعله JSON ودية.

جولة المكافأة

إذا كنت ترغب في نموذج django يحتوي على عرض أفضل لخط الأمر في python ، فاحرص على أن يكون طرازك الفرعي من الفئات التالية:

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))
            elif isinstance(f, DateTimeField):
                if f.value_from_object(self) is not None:
                    data[f.name] = f.value_from_object(self).timestamp()
            else:
                data[f.name] = None
            else:
                data[f.name] = f.value_from_object(self)
        return data

    class Meta:
        abstract = True

لذا ، على سبيل المثال ، إذا حددنا نماذجنا على هذا النحو:

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': 1426552454.926738,
'value': 1, 'value2': 2, 'reference1': 1, u'id': 1, 'reference2': [1]}

لقد وجدت حلًا أنيقًا للحصول على النتيجة:

افترض أن لديك كائن طراز o :

اتصل وحسب:

type(o).objects.filter(pk=o.pk).values().first()




django-models