0

我正在构建我的第一个真正的 django 应用程序,它具有不同的用户角色,并且正常的“创建用户配置文件的用户信号”方法不足。你们能帮帮我吗?

为了提供更多背景信息,以下是从功能角度来看的要求:

  • 新用户只能从管理员添加,并且将由非技术人员完成,因此我需要一个直观且简单的用户创建流程。
  • 每个用户都有一个具有不同需求和领域的角色(经理、员工、销售员等)。
  • 用户列表需要同时显示用户信息和角色/个人资料信息(登录名、电子邮件、姓名和个人资料上的额外信息)

初步方法:

因此,有了这个,我采用了推荐的方法,即创建一个链接到用户的 UserProfile 1 对 1 对象,为 UserProfile 提供一个设置角色的选择字段(在调用 get_profile 时了解我正在处理的内容很有用() ) 并将 UserProfile 子类化为 ManagerUserProfile、EmployeeUserProfile 等。

问题 :

这可以满足我在前端(管理员之外)的需求,但是在创建用户时设置信号以创建用户配置文件是没有意义的,因为我不知道应该仅根据用户信息创建哪种用户配置文件。

我的目标是一种创建特定用户的原子方式,同时它是相应的 EmployeeUserProfile/ManagerUserProfile,并具有简洁的管理表示。

我的一些想法:

  • 隐藏 UserAdmin 和 User Profile 管理员,为 EmployeeUserProfile/Manager/etc 创建 AdminModels 并内联 User 模型。这样,创建用户的人只会看到一个带有相应字段的“新经理”链接。但是他们可以在没有用户的情况下创建 UserProfile 吗?我怎样才能使这个原子?我如何防止删除用户或确保他们在允许保存配置文件之前提供所有必需的信息?-> 这种方法的问题:我似乎无法内联用户,因为它没有对 UserProfile 的 PK(反之亦然)。

  • 同样,隐藏 UserAdmin,公开子类配置文件 Admins,并反转信号。创建配置文件后,创建相应的用户。但为此,我需要能够从配置文件管理表单中提供用户字段(用户名、密码、电子邮件等)。

建议?

它是我的第一个应用程序,也许有一个巧妙的方法,但我还没有找到它。

感谢您抽时间阅读。干杯,泽塔。

4

2 回答 2

0

I would suggest that you create a custom form, custom admin view and use that for creating users in one request, with the exact logic you need. You can get an idea of how it's done by looking at django's own custom user creation process here.

于 2012-07-14T00:03:33.747 回答
0

我终于找到了一种方法来实现我所需要的。它可能不是最干净的,并且可以接受建议,但它可能会帮助遇到类似问题的人。

由于我只需要从管理员创建,我专注于此并构建以下内容。

表格.py

class RequiredInlineFormSet(BaseInlineFormSet):
    """
    Generates an inline formset that is required
    """

    def _construct_form(self, i, **kwargs):
        """
        Override the method to change the form attribute empty_permitted
        """
        form = super(RequiredInlineFormSet, self)._construct_form(i, **kwargs)
        form.empty_permitted = False
        self.can_delete = False
        return form

models.py(我没有使用信号在用户创建时自动创建配置文件)

class UserProfile(models.Model):
    # This field is required.
    user = models.OneToOneField(User)

    # Other fields here
    [.......]

    USER_TYPES = (
       ('manager', 'Manager'),
       ('employee', 'Employee'),
    )

    user_type = models.CharField(blank=True, max_length=10, choices=USER_TYPES)

    def __unicode__(self):
        return self.user.username


class EmployeeProfile(UserProfile):
    [...]

    def __init__(self, *args, **kwargs):
        super(EmployeeProfile, self).__init__(*args, **kwargs)
        self.user_type = 'employee'

class ManagerProfile(UserProfile):
    [...]

    def __init__(self, *args, **kwargs):
        super(ManagerProfile, self).__init__(*args, **kwargs)
        self.user_type = 'manager'


class Manager(User):
    class Meta:
        proxy = True
        #app_label = 'auth'
        verbose_name = 'manager'
        verbose_name_plural = 'managers'

    def save(self, *args, **kwargs):
        self.is_staff = True
        super(Manager, self).save(*args, **kwargs) # Call the "real" save() method.
        g = Group.objects.get(name='Managers') 
        g.user_set.add(self)


class Employee(User):
    class Meta:
        proxy = True
        #app_label = 'auth'
        verbose_name = 'employee'
        verbose_name_plural = 'employees'

    def save(self, *args, **kwargs):
        self.is_staff = False
        super(Employee, self).save(*args, **kwargs) # Call the "real" save() method.
        g = Group.objects.get(name='Employees') 
        g.user_set.add(self)

管理员.py

class ManagerProfileAdmin(admin.StackedInline):
    model = ManagerProfile
    max_num = 1
    extra = 1
    formset = RequiredInlineFormSet


class EmployeeProfileAdmin(admin.StackedInline):
    model = EmployeeProfile
    max_num = 1
    extra = 1
    formset = RequiredInlineFormSet

class ManagerAdmin(UserAdmin):
    """
    Options for the admin interface
    """
    inlines = [ManagerProfileAdmin]

    def queryset(self, request):
        qs = super(UserAdmin, self).queryset(request)
        qs = qs.filter(Q(userprofile__user_type='manager'))

        return qs


class EmployeeAdmin(UserAdmin):
    """
    Options for the admin interface
    """
    inlines = [EmployeeProfileAdmin]

    def queryset(self, request):
        qs = super(UserAdmin, self).queryset(request)
        qs = qs.filter(Q(userprofile__user_type='employee'))

        return qs

admin.site.unregister(User)
admin.site.register(Manager, ManagerAdmin)
admin.site.register(Employee, EmployeeAdmin)
于 2012-07-20T15:15:02.700 回答