سؤال

أنا بحاجة إلى تخزين بعض البيانات في جانغو نموذج.هذه البيانات ليست متساوية في جميع الحالات من هذا النموذج.

في البداية فكرت في subclassing النموذج ، ولكن أحاول الحفاظ على التطبيق مرنة.إذا كنت تستخدم فرعية, سوف تحتاج إلى إنشاء فئة كاملة في كل مرة كنت بحاجة إلى نوع جديد من وجوه ، و هذا ليس جيدا.أنا أيضا في نهاية المطاف مع الكثير من الفئات الفرعية فقط لتخزين زوج من حقول إضافية.

أشعر حقا أن القاموس قد يكون أفضل نهج, ولكن لا يوجد شيء في جانغو وثائق حول تخزين القاموس في جانغو نموذج (أو أنا لا يمكن العثور عليه).

أي أدلة ؟

هل كانت مفيدة؟

المحلول

إذا انها القاموس حقا مثل البيانات التعسفي كنت تبحث عن ربما يمكنك استخدام الإعداد مستويين مع نموذج واحد وهذا هو وعاء ونموذج آخر هذا أزواج قيمة المفتاح. وكنت إنشاء مثيل من الحاوية، وخلق كل من الحالات قيمة المفتاح، وربط مجموعة من الحالات قيمة المفتاح مع المثيل الحاوية. شيء من هذا القبيل:

class Dicty(models.Model):
    name      = models.CharField(max_length=50)

class KeyVal(models.Model):
    container = models.ForeignKey(Dicty, db_index=True)
    key       = models.CharField(max_length=240, db_index=True)
    value     = models.CharField(max_length=240, db_index=True)

وانها ليست جميلة، ولكنها سوف تتيح لك الوصول / البحث في أحشاء من القاموس باستخدام DB في حين ورطة / تسلسل الحل لن تفعل ذلك.

نصائح أخرى

إذا كنت لا تحتاج إلى الاستعلام عن طريق أي من هذه البيانات إضافية، ثم يمكنك تخزين أنها القاموس تسلسل. استخدام repr لتحويل القاموس إلى سلسلة، وeval لتحويل سلسلة مرة أخرى إلى القاموس. رعاية مع وحدة التقييم أنه لا يوجد بيانات المستخدم في القاموس، أو استخدام تطبيق safe_eval.

وجئت إلى هذا المنصب من قبل نتيجة غوغل 4rth إلى "كائن مخزن جانغو"

وقليلا في وقت متأخر، ولكن جانغو-picklefield يبدو وكأنه حل جيد بالنسبة لي.

مثال من وثيقة:

لاستخدام، فقط تعريف حقل في النموذج الخاص بك:

>>> from picklefield.fields import PickledObjectField
>>> class SomeObject(models.Model):
>>>     args = PickledObjectField()

وتعيين ما تريد (طالما انها picklable) إلى أرضية الملعب:

>>> obj = SomeObject()
>>> obj.args = ['fancy', {'objects': 'inside'}]
>>> obj.save()

آخر نظيفة وسريعة الحل يمكن العثور عليها هنا: https://github.com/bradjasper/django-jsonfield

للراحة أنا نسخ التعليمات البسيطة.

تثبيت

pip install jsonfield

الاستخدام

from django.db import models
from jsonfield import JSONField

class MyModel(models.Model):
    json = JSONField()

كما نيد أجاب أنك لن تكون قادرة على الاستعلام "بعض البيانات" إذا كنت تستخدم القاموس النهج.

إذا كنت لا تزال بحاجة إلى تخزين القواميس فإن أفضل نهج الآن هو PickleField الدرجة موثقة في مارتي Alchin كتاب جديد برو جانغو.هذا الأسلوب يستخدم الثعبان خصائص الطبقة المخلل/unpickle الثعبان كائن فقط على الطلب ، على أن يتم تخزينها في حقل نموذج.

أساسيات هذا النهج هو استخدام جانغو contibute_to_class طريقة حيوي إضافة حقل جديد إلى النموذج الخاص بك ويستخدم getattr/setattr للقيام التسلسلية على الطلب.

واحدة من عدد قليل أمثلة على الانترنت يمكن أن تجد أن يشبه هذا التعريف JSONField.

ولست متأكدا متأكدا بالضبط طبيعة المشكلة التي تحاول حلها، ولكن يبدو مشابها الغريب أن <لأ href = "http://code.google.com/appengine/docs/datastore/ expandoclass.html "يختلط =" نوفولو noreferrer "> محرك تطبيقات جوجل في جداول كبيرة Expando .

وExpandos تسمح لك لتحديد وتخزين حقول إضافية على مثيل كائن المدعومة من قاعدة بيانات في وقت التشغيل. أن أقتبس من المستندات:

import datetime
from google.appengine.ext import db

class Song(db.Expando):
  title = db.StringProperty()

crazy = Song(title='Crazy like a diamond',
             author='Lucy Sky',
             publish_date='yesterday',
             rating=5.0)

crazy.last_minute_note=db.Text('Get a train to the station.')

ومحرك جوجل التطبيق يدعم حاليا كلا بيثون والإطار جانغو. قد يكون من المفيد النظر في ما إذا كان هذا هو أفضل وسيلة للتعبير عن النماذج الخاصة بك.

ونماذج قواعد البيانات العلائقية التقليدية لم يكن لديك هذا النوع من المرونة الأعمدة بالإضافة. إذا أنواع البيانات الخاصة بك هي بسيطة جدا هل يمكن كسر من فلسفة RDBMS التقليدية والإختراق القيم في عمود واحد عن طريق التسلسل ك <لأ href = "https://stackoverflow.com/questions/402217/how-to-store-a-dictionary- على واحد في جانغو نموذج # 402248 "> @ يقترح نيد باتشلدر . ومع ذلك، إذا كنت <م> هل لديك لاستخدام RDBMS، بفك نموذج الميراث وربما كان وسيلة للذهاب. والجدير بالذكر، أنه سيتم إنشاء واحدة ل -one الأجنبية الرئيسية بالنسبة للحصول على كل مستوى من الاشتقاق.

وأنا أتفق التي تحتاج إلى الامتناع حشو البيانات المنظمة خلاف ذلك في عمود واحد. ولكن إذا كان يجب أن تفعل ذلك، بفك له XMLField البناء في.

وهناك أيضا JSONField في snipplets جانغو.

ويجري "لا تساوي جميع الحالات من طراز" يبدو لي وكأنه مباراة جيدة ل"قاعدة بيانات خالية من مخطط". كاوتش دي بي هو الطفل المدلل لهذا النهج وقد تفكر في ذلك.

في مشروع انتقلت العديد من الجداول التي لم يلعب لطيفة جدا مع جانغو مكتب إدارة السجلات لأكثر من كاوتش دي بي وأنا سعيد للغاية بذلك. يمكنني استخدام كاوتش دي بي-الثعبان دون أي من وحدات كاوتش دي بي جانغو محددة. وصف لنموذج البيانات يمكن العثور على هنا . حركة من خمس "نماذج" في جانغو ل3 "نماذج" في جانغو و "قاعدة بيانات" واحد كاوتش دي بي في الواقع انخفاض طفيف خطوط الإجمالية من التعليمات البرمجية في التطبيق الخاص بي.

هذا السؤال هو قديم ولكن كنت أعاني من نفس المشكلة انتهت هنا الجواب المختار لم استطع حل مشكلتي بعد الآن.

إذا كنت ترغب في تخزين القواميس في جانغو أو بقية Api ، إما أن تستخدم الكائنات في الواجهة الأمامية ، أو بسبب البيانات الخاصة بك لن يكون بالضرورة نفس هيكل الحل اعتدت يمكن أن تساعدك.

عند حفظ البيانات في API الخاص بك, استخدام json.تفريغ() الأسلوب أن يكون قادرا على تخزينها في السليم تنسيق json, كما هو موضح في هذا السؤال.

إذا كنت تستخدم هذا الهيكل ، البيانات الخاصة بك سوف تكون بالفعل في تنسيق json ودعا إلى أن تكون في الواجهة الأمامية مع JSON.تحليل() في اياكس (أو أيا كان) المكالمة.

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

وحشو بيانات عشوائية في جدول SQL ليست ذكية، إلا انها حقا البيانات غير العلائقية. إذا كان هذا هو الحال، وتحديد المشكلة، ونحن قد تكون قادرة على مساعدة.

يتضمن

وجانغو-جيو و"DictionaryField" قد تجد مفيدة:

HTTP: / /code.google.com/p/django-geo/source/browse/trunk/fields.py؟r=13#49

في عام، إذا كنت لا تحتاج إلى الاستفسار عبر استخدام بيانات نهج بدون تسوية لتجنب استفسارات إضافية. إعدادات المستخدم هي مثال جيد جدا!

إذا كنت تستخدم بوستجرس، يمكنك استخدام حقل hstore: <لأ href = "https://docs.djangoproject.com/en/1.10/ref/contrib/postgres/fields/#hstorefield" يختلط = "نوفولو "> https://docs.djangoproject.com/en/1.10/ref/contrib/postgres/fields/#hstorefield .

ويمكنني استخدام حيز النص وjson.loads() / json.dumps()

models.py

import json
from django.db import models

class Item(models.Model):
    data = models.TextField(blank=True, null=True, default='{}')

    def save(self, *args, **kwargs):
        ## load the current string and
        ## convert string to python dictionary
        data_dict = json.loads(self.data)

        ## do something with the dictionary
        for something in somethings:
            data_dict[something] = some_function(something)

        ## if it is empty, save it back to a '{}' string,
        ## if it is not empty, convert the dictionary back to a json string
        if not data_dict:
            self.data = '{}'
        else:
            self.data = json.dumps(data_dict)


        super(Item, self).save(*args, **kwargs)

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top