Django模型 - 如何在字典中存储字段

时间:2017-04-01 11:48:23

标签: python django orm model

我有一个相当简单的用户模型完美地工作。 为了减少代码冗余,我尝试将字段存储在一个胜利中,原因很简单。

示例:

def get_social_token(self,social_net=""):
   return self.social_dict[social_net]["token"]

如果我不做这样的结构,我必须做一些“if / then ... elif ... else”。 当然,每当我决定在我的应用程序中添加新的社交网络时,我都需要修改我的代码。

我尝试了两种不同的方法,它们都给了我相同的结果:

  • 没有错误
  • 实际上未在DB
  • 中检测到并创建任何字段

我想提一下,如果我使用“传统方式”来实现这种行为,例如:

  • twitter_social_token = EncryptedCharField(max_length = 500,默认='',空白=真,空=真)

它非常有效,因此它来自字典的使用。

有什么想法解决这个问题吗? 顺便说一句。我宁愿避免使用新模型和外键...只有一对一的关联,我宁愿不必执行任何“加入”或在另一个表中选择......

贝娄,你会发现我做的两次尝试都行不通(我不知道为什么):

首次尝试:

social_fields = {
    'twitter' : {
        'token'  : EncryptedCharField(max_length=500, default='', blank=True, null=True),
        'secret' : EncryptedCharField(max_length=500, default='', blank=True, null=True)
    },
    'facebook' : {
        'token'  : EncryptedCharField(max_length=500, default='', blank=True, null=True),
        'secret' : EncryptedCharField(max_length=500, default='', blank=True, null=True)
    },
    'gplus' : {
        'token'  : EncryptedCharField(max_length=500, default='', blank=True, null=True),
        'secret' : EncryptedCharField(max_length=500, default='', blank=True, null=True)
    },
    'linkedin' : {
        'token'  : EncryptedCharField(max_length=500, default='', blank=True, null=True),
        'secret' : EncryptedCharField(max_length=500, default='', blank=True, null=True)
    },
}

第二次尝试:

social_tokens = dict()

social_tokens["twitter"] = dict()
social_tokens["facebook"] = dict()
social_tokens["linkedin"] = dict()
social_tokens["gplus"] = dict()

social_tokens["twitter"]["token"] = EncryptedCharField(max_length=500, default='', blank=True, null=True)
social_tokens["twitter"]["secret"] = EncryptedCharField(max_length=500, default='', blank=True, null=True)

social_tokens["facebook"]["token"] = EncryptedCharField(max_length=500, default='', blank=True, null=True)
social_tokens["facebook"]["secret"] = EncryptedCharField(max_length=500, default='', blank=True, null=True)

social_tokens["linkedin"]["token"] = EncryptedCharField(max_length=500, default='', blank=True, null=True)
social_tokens["linkedin"]["secret"] = EncryptedCharField(max_length=500, default='', blank=True, null=True)

social_tokens["gplus"]["token"] = EncryptedCharField(max_length=500, default='', blank=True, null=True)
social_tokens["gplus"]["secret"] = EncryptedCharField(max_length=500, default='', blank=True, null=True)

感谢亲爱的朋友的帮助,

乔纳森

2 个答案:

答案 0 :(得分:2)

据我所知,不使用加入你有3种不同的方式:

  

django-picklefield提供了一个pickle对象的实现   领域。这些字段可以包含任何可选对象。

从他们的文档,到使用;只需在模型中定义一个字段:

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

并将您喜欢的任何内容(只要它可以选择)分配给该字段:

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

django-jsonfield是一个可重复使用的Django字段,允许您存储   在您的模型中验证了JSON。   它默默地负责序列化。要使用,只需添加字段即可   对你的一个模特。

要使用,只需安装软件包,然后使用以下字段:

from django.db import models
import jsonfield

class MyModel(models.Model):
    the_json = jsonfield.JSONField()
  

用于存储字符串到字符串的映射的字段。 Python数据   使用的类型是字典。

from django.contrib.postgres.fields import HStoreField
from django.db import models

class Dog(models.Model):
    name = models.CharField(max_length=200)
    data = HStoreField()

Dog.objects.create(name='Rufus', data={'breed': 'labrador'})

答案 1 :(得分:1)

它会定义有效,但正如您所见,我使用加密字段以保护用户的令牌和secret_tokens安全。

我希望这不是坏事或某种反模式。 随意分享更好的方法。

我刚刚发现了一种解决方法,它实际上可以按照我想要的方式工作,即使从我的角度来看它也不是非常有效。

您可以在此处访问数据:

from application.models import *
tmp_user = CustomUser.objects.get(username="random_username")

print (getattr(tmp_user, tmp_user.social_fields["twitter"]["token"]))
>>> e72e16c7e42f292c6912e7710c838347ae178b4a ### This token is a fake !

以下是设法执行此操作的方法:

twitter_token          = EncryptedCharField(max_length=500, default='', blank=True, null=True)
twitter_token_secret   = EncryptedCharField(max_length=500, default='', blank=True, null=True)

facebook_token         = EncryptedCharField(max_length=500, default='', blank=True, null=True)
facebook_token_secret  = EncryptedCharField(max_length=500, default='', blank=True, null=True)

gplus_token            = EncryptedCharField(max_length=500, default='', blank=True, null=True)
gplus_token_secret     = EncryptedCharField(max_length=500, default='', blank=True, null=True)

linkedin_token         = EncryptedCharField(max_length=500, default='', blank=True, null=True)
linkedin_token_secret  = EncryptedCharField(max_length=500, default='', blank=True, null=True)

social_fields = {
    'twitter' : {
        'token'  : "twitter_token",
        'secret' : "twitter_token_secret"
    },
    'facebook' : {
        'token'  : "facebook_token",
        'secret' : "facebook_token_secret"
    },
    'gplus' : {
        'token'  : "gplus_token",
        'secret' : "gplus_token_secret"
    },
    'linkedin' : {
        'token'  : "linkedin_token",
        'secret' : "linkedin_token_secret"
    },
}