代码之家  ›  专栏  ›  技术社区  ›  ViaTech

django models,在重写save()方法时收集models.autofield编号

  •  0
  • ViaTech  · 技术社区  · 6 年前

    我有一个姜戈模型 用户 然后是一个单独的模型 访问级别 .

    保存时 用户 使用Django的ORM,我还想在 访问级别 表。

    我的问题是 PK 属于 访问级别 PK 属于 用户 而我似乎无法超越 save() 方法并收集 id = models.AutoField(primary_key=True) .

    这是我的相关代码:

    class Users(models.Model):
    
        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
    
        # pk
        id = models.AutoField(primary_key=True)
    
        # client_id
        client_id = models.IntegerField(null=False, blank=False, default="-1")
    
        ...
    
        def save(self, *args, **kwargs):
            AccessLevel(user_id=self.id,
                    client_id=self.client_id).save(using='default')
    
            print('Access Level Set for User while saving')
            super(Users, self).save(*args, **kwargs)
    

    以下是 访问级

    class AccessLevel(models.Model):
    
        # pk
        id = models.AutoField(primary_key=True)
    
        # this is the id for the user, but I get null value
        user_id = models.IntegerField(null=False, blank=False, default="-1")
    
        client_id = models.IntegerField(null=False, blank=False, default="-1")
    

    当我调用此代码时,会得到错误。

    root_user = Users(username='root',
                          email='root',
                          first_name='root',
                          last_name='root',
                          phone='root',
                          password=make_password(default_root_pw),
                          type='root').save(using='default')
    

    这是错误

    django.db.utils.integrityerror:列“user_id”中的空值违反了非空约束 详细信息:失败行包含(3,空,-1,0,0,0,0,0,0,0,0,0,0,0,0,0)。

    1 回复  |  直到 6 年前
        1
  •  2
  •   Daniel Roseman    6 年前

    首先,绝对不要对这些值使用integerfield。它们是外键,您应该使用foreignkey字段。这些应该叫 user client -请注意,您仍然可以像以前一样访问基础ID。

    (此外,无需明确声明 id 字段;而且您几乎不应该重写 __init__ 在一个模型中,尤其是没有任何点覆盖只调用超级方法的方法。把那个拿开。)

    class AccessLevel(models.Model):
        user = models.ForeignKey('Users', null=False, blank=False)
        client = models.ForeignKey('Client', null=False, blank=False)
    
    class Users(models.Model):
        client = models.ForeignKey('Client', null=False, blank=False)
    

    现在,对于您的实际问题,ID是由数据库分配的,只有在保存之后才会发生。所以你应该创建你的相关项目 之后 那。

    def save(self, *args, **kwargs):
        super(Users, self).save(*args, **kwargs)
        AccessLevel(user_id=self.id,
                client_id=self.client_id).save(using='default')
    
        print('Access Level Set for User while saving')
    

    创建该项的另一种方法可能更清楚一些,是使用外键提供的访问器:

    self.accesslevel_set.create(client_id=self.client_id)
    

    最后,这可能比 a post-save signal ,而不是在保存方法中。