【问题标题】:create row of date while creating superuser创建超级用户时创建日期行
【发布时间】:2013-07-22 07:34:51
【问题描述】:

models.py

TITLE = (
    ('Classroom', 'Classroom'),
    ('Playground', 'Playground'),
    ('Staff Room','Staff Room'),
)

class Location(models.Model):
    user = models.ForeignKey(User,null=True)
    title = models.CharField('Incident Type', max_length=200,default=TITLE)
    parent_location_id = models.CharField('Parent Location', max_length=100, null=True, blank=True)
    is_active = models.BooleanField('Is Active', default=True)

def location_title(sender, instance, created, **kwargs):        
    if instance.is_superuser and not instance.location.is_active:

        instance.location.is_active=True
        instance.location.save()

post_save.connect(location_title, sender=User)

我想在特定条件下将默认数据插入数据库。这应该在通过manage.py createsuperuser 注释创建超级用户时发生。

我不知道使用 django 是否可行,但这是必需的。我尝试使用上面的代码。我收到错误“AttributeError: 'User' object has no attribute 'location' " 同时创建超级用户。

我需要的样本如下

【问题讨论】:

  • 他们是否有机会实现这一点。
  • 这是什么django版本?
  • 我使用的是 Django 1.3.7
  • 那么你必须阅读这个:docs.djangoproject.com/en/1.3/topics/auth/…
  • 1.如果您不愿意升级到包含自定义用户模型的 Django 1.5,那么您将不得不使用配置文件,如 @mariodev 所述。 2. 您看到的错误“未定义用户配置文件”可能是因为您尚未定义 AUTH_PROFILE_MODULE 设置。再次查看上面的链接。 3. 您应该考虑为您的用户创建一个自定义模型管理器,这将允许您在创建超级用户时修改位置。请参阅文档here,但这在 Django 1.3 中可能不可用

标签: python django django-models django-forms django-admin


【解决方案1】:

试试这个函数作为信号处理器:

def location_title(sender, instance, created, **kwargs):
    # Don't fire up on updates.
    if not created:
        return

    # Only handle new superusers.
    if not instance.is_superuser or not instance.is_active:
        return

    # Create a `Location` entry for new superuser.
    l = Location(user_id=instance.pk)
    l.save()

post_save.connect(location_title, sender=User)

向模型字段添加选择:

Django CharField 有一个命名参数choices,它允许您为最终用户提供可能值的列表,并在表单中对它们进行适当的验证。可迭代的格式如下<internal_value>, <display_value>。一旦向字段传递了choices 参数,您就可以使用instance.get_<field_name>_display() 方法访问与其内部值相关的显示值。

可迭代的选项可能如下所示:

class Location(models.Model):
    class Title:
        CLASSROOM = 'classroom'
        PLAYGROUND = 'playground'
        STAFF_ROOM = 'staff_room'

    TITLE_CHOICES = (
        (Title.CLASSROOM, 'Classroom'),
        (Title.PLAYGROUND, 'Playground'),
        (Title.STAFF_ROOM, 'Staff Room'),
    )

    user = models.ForeignKey(User,null=True)
    title = models.CharField('Incident Type', max_length=200,choices=TITLE_CHOICES,default=Title.CLASSROOM)
    parent_location_id = models.CharField('Parent Location', max_length=100, null=True, blank=True)
    is_active = models.BooleanField('Is Active', default=True)

最终解决方案如下:

class Location(models.Model):
    class Title:
        CLASSROOM = 'classroom'
        PLAYGROUND = 'playground'
        STAFF_ROOM = 'staff_room'

    BASE_LOCATION = Title.CLASSROOM

    TITLE_CHOICES = (
        (Title.CLASSROOM, 'Classroom'),
        (Title.PLAYGROUND, 'Playground'),
        (Title.STAFF_ROOM, 'Staff Room'),
    )

    user = models.ForeignKey(User,null=True)
    title = models.CharField('Incident Type', max_length=200,choices=TITLE_CHOICES,default=Title.CLASSROOM)
    parent_location_id = models.CharField('Parent Location', max_length=100, null=True, blank=True)
    is_active = models.BooleanField('Is Active', default=True)


def location_title(sender, instance, created, **kwargs):
    # Don't fire up on updates.
    if not created:
        return

    # Only handle new superusers.
    if not instance.is_superuser or not instance.is_active:
        return

    # Create a `Location` entry for new superuser.
    base = Location(user_id=instance.pk, title=Location.BASE_LOCATION)
    base.save()

    for value, _ in Location.TITLE_CHOICES:
        if value == Location.BASE_LOCATION:
            continue

        l = Location(user_id=instance.pk, title=value, parent_location_id=base.pk)
        l.save()

post_save.connect(location_title, sender=User)

【讨论】:

  • 上面的代码正在位置表中创建一行。我试图在标题字段中包含选项,以便我必须在数据库中创建默认数据。我想要示例中给出的输出图片。你能指导我怎么做吗?
  • 如果您想在标题字段中包含choices,请使用具有值TITLE 的命名参数choices。要设置默认值,请使用 TITLE 元组的元素,即 TITLE[0][0] 使 Classroom 作为 default 命名参数的默认值。选择元组是一对 <internal_value>, <display_value> 的元组,其中 internal_value 应该是内部使用的值 - 在脚本、数据库等中,而 display_value 是显示给前端用户的值。
  • 刚才我检查了你的评论,看起来是一种不同的方法,你能解释一下怎么做吗。
  • 我尝试使用信号处理程序,很抱歉它没有在 db 中创建默认值和选择值。
  • default and choices value in db 是什么意思?目前,信号处理程序创建一个具有默认值的 Location 条目。您想为每个创建的超级用户创建所有 4 个Location 对象吗?
【解决方案2】:

当您创建用户或超级用户时,模型实例已创建,但它没有对应的location 行。因此,访问 instance.location.is_active 会给您带来错误。

您可以更新信号处理程序以首先创建location 实例,然后设置适当的属性。如下:

def location_title(sender, instance, created, **kwargs):     
    #also check for created flag   
    if created and instance.is_superuser:
        location = Location(user=instance)
        location.is_active=True
        location.save()

post_save.connect(location_title, sender=User)

如果您想选择title 字段,您可以在字段中定义它。你对title字段的定义不正确,改成

title = models.CharField('Incident Type', max_length=200, choices=TITLE,  
                         default='Classroom') 

您错误地使用了detfault=TITLE 而不是choices=TITLE

【讨论】:

  • 如果创建而不是 instance.is_superuser:-->在数据库中创建了一行数据。我想将提到的选项包含在标题字段中。如何将其包含在标题字段中。跨度>
  • @user2086641,您也可以设置location.title='Classroom'。请注意,LocationUser 具有 OneToOne 关系,因此一个用户不能有多个位置对象(具有不同的标题)。
  • 是否可以与用户表建立 ForeignKey 关系。
  • @user2086641,检查使用choices属性的更新答案。
  • @user2086641,是的,ForeignKey() 是可能的。
猜你喜欢
  • 2021-10-13
  • 1970-01-01
  • 2022-01-25
  • 2012-12-13
  • 2021-11-16
  • 2014-05-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多