【问题标题】:Django Models - How to store fields in a dictDjango 模型 - 如何在字典中存储字段
【发布时间】:2017-08-26 15:47:00
【问题描述】:

我有一个相当简单的用户模型,可以完美运行。 为了减少代码冗余,我尝试将字段存储在字典中,原因您很容易猜到。

例子:

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

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

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

  • 没有错误
  • 在数据库中实际上没有检测到和创建字段

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

  • twitter_social_token = EncryptedCharField(max_length=500, default='', blank=True, null=True)

它完美地工作,所以它来自字典的使用。

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

Bellow,你会发现我做的两次尝试都不起作用(我不知道为什么):

第一次尝试:

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)

感谢各位朋友的帮助,

乔纳森

【问题讨论】:

  • 不要发布代码截图;贴出实际代码。
  • 哦,抱歉,我已经修复了我的消息。

标签: python django orm model


【解决方案1】:

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

django-picklefield 提供了一个腌制对象的实现 场地。此类字段可以包含任何可腌制对象。

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

>>> 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'})

【讨论】:

    【解决方案2】:

    它肯定可以工作,但是正如您所见,我使用加密字段来保护我的用户令牌和 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"
        },
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-03-29
      • 2021-09-15
      • 2010-09-28
      • 2016-02-11
      • 2018-02-16
      • 2017-06-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多