0

私は、さまざまなユーザーの役割を持つ最初の実際の django アプリケーションを構築していますが、通常の「UserProfile を作成するユーザー シグナル」アプローチでは不十分です。手伝ってくれませんか?

より多くのコンテキストを提供するために、機能的な観点からの要件は次のとおりです。

  • 新しいユーザーは管理者からのみ追加され、技術に精通していない人が行うため、直感的で簡単なユーザー作成フローが必要です。
  • 各ユーザーには、さまざまなニーズとフィールドを持つ役割 (マネージャー、従業員、セールスマンなど) があります。
  • ユーザーリストには、ユーザー情報と役割/プロファイル情報 (ログイン、電子メール、名前、およびプロファイルの追加情報) の両方を表示する必要があります。

初期アプローチ:

これを武器に、ユーザーにリンクされた UserProfile 1 対 1 オブジェクトを作成するという推奨アプローチを採用し、ロールが設定されている選択肢フィールドを UserProfile に提供します (get_profile を呼び出すときに何を扱っているかを知るのに役立ちます)。 () ) UserProfile を ManagerUserProfile、EmployeeUserProfile などにサブクラス化します。

問題 :

これはフロントエンド (管理者の外) で私のニーズに合わせて機能しますが、ユーザーが作成されたときに UserProfile を作成するようにシグナルを設定することは無意味です。

私が目指しているのは、特定のユーザーを作成するアトミックな方法と、それに対応する EmployeeUserProfile/ManagerUserProfile を同時に作成し、適切な管理者を表現することです。

私のアイデアのいくつか:

  • UserAdmin および User Profile 管理者を非表示にし、EmployeeUserProfile/Manager/etc の AdminModel を作成し、User モデルをインライン化します。そうすれば、ユーザーを作成する人には、対応するフィールドを含む「新しいマネージャー」リンクのみが表示されます。しかし、ユーザーなしで UserProfile を作成することはできますか? どうすればこれをアトミックにできますか? プロファイルの保存を許可する前に、ユーザーが削除されないようにするか、必要な情報をすべて提供するようにするにはどうすればよいですか? -> このアプローチの問題: UserProfile への PK がないため、ユーザーをインライン化できないようです (逆です)。

  • ここでも、UserAdmin を非表示にし、サブクラス化されたプロファイル Admins を公開して、信号を逆にします。プロファイルが作成されたら、対応するユーザーを作成します。しかし、このためには、プロファイル管理フォームからユーザー フィールド (ユーザー名、パス、電子メールなど) を提供できる必要があります。

提案?

それは私の最初のアプリであり、おそらくこれにはきちんとした方法がありますが、まだ見つけていません.

これを読んでくれてありがとう。乾杯、ゼータ。

4

2 に答える 2

0

カスタムフォーム、カスタム管理ビューを作成し、それを使用して、必要な正確なロジックを使用して、1 つのリクエストでユーザーを作成することをお勧めします。ここで、django 独自のカスタム ユーザー作成プロセスを見ると、それがどのように行われるかがわかります

于 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)

admin.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 に答える