首页Django正文

怎么封装model里某个字段的访问和更新

提问已结 3 97
lyhabc
lyhabcDjango实战会员2018年10月21日 12:04

model代码是这样


class DBAsset(models.Model):
    DBTYPE_ITEMS = (
        ('mssql', 'mssql'),
        ('mysql', 'mysql'),
        ('mongodb', 'mongodb'),
    )

    OSTYPE_ITEMS = (
        ('windows', 'windows'),
        ('linux', 'linux'),
    )

    STATUS_ITEMS = (
        (1, '上线'),
        (2, '下架'),
    )

    INTERNAL_ITEMS = (
        (0, '不在内网'),
        (1, '在内网'),
    )
    public_ip = models.GenericIPAddressField(max_length=32, null=False, verbose_name='公网IP')
    internal_ip = models.GenericIPAddressField(max_length=32, verbose_name=' 内网IP')
    port = models.IntegerField(null=False, verbose_name='端口')
    hostname = models.CharField(max_length=128,null=False,unique=True, verbose_name='主机名')
    dbtype = models.CharField(max_length=20, choices=DBTYPE_ITEMS,  verbose_name='数据库类型')
    ostype = models.CharField(max_length=20, choices=OSTYPE_ITEMS,  verbose_name='操作系统类型')
    status = models.PositiveIntegerField(default=1, choices=STATUS_ITEMS, verbose_name="状态")
    is_internal = models.PositiveIntegerField(default=0, choices=INTERNAL_ITEMS, verbose_name="是否在内网")
    project = models.ForeignKey(Project,related_name='dbassets',verbose_name="项目")
    dbuser = models.CharField(max_length=20, null=False,  verbose_name='数据库用户')
    _dbuserpassword = models.CharField(max_length=200, null=False,  verbose_name='数据库密码')
    date_created = models.DateTimeField(default=timezone.now, null=False, blank=True,verbose_name='创建时间')

    @property
    def dbuserpassword(self):
        password = signer.unsign(self._dbuserpassword)
        if password:
            return password
        else:
            return ""

    @dbuserpassword.setter
    def dbuserpassword(self, password_raw):
        self._dbuserpassword = signer.sign(password_raw)

    def __unicode__(self):
        return '{0.hostname}({0.public_ip})'.format(self)

    def __str__(self):
        return '{0.hostname}({0.public_ip})'.format(self)

    class Meta:
        # unique_together = (("public_ip", "port"),)
        verbose_name = verbose_name_plural = '数据库资产'

_dbuserpassword字段是不能直接访问和更新的,要经过属性函数进行加密和解密

现在的问题是,前端怎么对这个字段进行封装,类似django自带的auth,user表有set_password函数,创建用户有create_user和create_superuser函数

如果我前端对这个字段直接访问会报错 aaa= DBAsset.objects.all().first()

    print aaa.dbuserpassword
    aaa.dbuserpassword = '6666666'
    aaa.save(update_fields=['dbuserpassword'])

ValueError: The following fields do not exist in this model or are m2m fields: dbuserpassword

回帖
  • the5fire
    2018年10月21日 13:54
    aaa.save(update_fields=['_dbuserpassword'])
    

    你的字段是什么,这里就填什么

  • lyhabc
    lyhabc(楼主)
    2018年10月21日 14:10

    通过model 实例更新dbuserpassword 可以用这种方法

    aaa= DBAsset.objects.get(dbuser='ss')
    print aaa.dbuserpassword
    aaa.dbuserpassword = '6666666'
    aaa.save(update_fields=['dbuserpassword'])
    

    但是,通过queryset,怎么更新和创建呢,比如下面代码

    from asset.models import Project,DBAsset
    proin = Project.objects.get(id=5)
    DBAsset.objects.update_or_create(public_ip='192.168.1.5',internal_ip='192.168.12.7',port=77,hostname='dajiahao',dbtype='mssql',ostype='windows',
                                     status=1,is_internal=0,project=proin,dbuser='ss',dbuserpassword='7777777')
    
    
    DBAsset.objects.filter(dbuser='ss').update(dbuserpassword='7777777')
    

    直接用dbuserpassword的话,会报错 FieldError: Cannot resolve keyword 'dbuserpassword' into field. Choices are: _dbuserpassword, date_created, dbtype, dbuser, hostname, id, internal_ip, is_internal, ostype, port, project, project_id, public_ip, status

  • the5fire
    2018年10月22日 16:36

    楼主自己结一下贴{[偷笑]}

    你应该已经懂了问题 在哪了,话说最终还得看源码。