0

複数のプロファイルで Django のユーザー認証機能を使用することは可能ですか?

現在、これを含む settings.py ファイルがあります。

AUTH_PROFILE_MODULE = 'auth.UserProfileA'

そして、これを含む models.py ファイル:

from django.db import models
from django.contrib.auth.models import User

class UserProfileA(models.Model):
    company = models.CharField(max_length=30)
    user = models.ForeignKey(User, unique=True)

そうすれば、ユーザーがログインすると、ユーザーには get_profile() メソッドがあるため、プロファイルを簡単に取得できます。ただし、UserProfileB を追加したいと思います。少し調べてみると、AUTH_PROFILE_MODULE として使用するスーパークラスを作成し、UserProfileA と UserProfileB の両方をそのスーパークラスから継承させることが出発点のようです。問題は、get_profile() メソッドが正しいプロファイルを返すとは思わないことです。スーパークラスのインスタンスを返します。私はJavaのバックグラウンド(ポリモーフィズム)から来ているので、何をすべきか正確にはわかりません。

ありがとう!

編集:

このサイトhttp://djangosnippets.org/snippets/1031/で見つけた「継承ハック」と呼ばれるものを介してそれを行う方法を見つけました

それは非常にうまく機能しますが、このようなことが自動的に行われるJavaのバックグラウンドから来て、誰かがこれをコード化してPythonでそれを行うために「ハック」と呼ばなければならなかったという事実に少し不安です. Pythonがこれを有効にしない理由はありますか?

4

4 に答える 4

4

したがって、これから直面する問題は、プロファイルに必要なものが何であれ、それをある種のデータベースに保持する必要があるということです。基本的に、django のすべてのバックエンドはリレーショナルであるため、永続化されたオブジェクトのすべてのフィールドがテーブルのすべての行に存在します。欲しいものを手に入れる方法はいくつかあります。

Django は継承をサポートしています。 リストされている手法を使用して、ポリモーフィックな方法で妥当な結果を得ることができます。

最も直接的なアプローチは、複数のテーブル継承を使用することです。だいたい:

class UserProfile(models.Model):
    # set settings.AUTH_PROFILE_MODULE to this class!
    pass

class UserProfileA(UserProfile):
    pass

class UserProfileB(UserProfile):
    pass

使用するには:

try:
    profile = user.get_profile().userprofilea
    # user profile is UserProfileA
except UserProfileA.DoesNotExist:
    # user profile wasn't UserProfileB
    pass
try:
    profile = user.get_profile().userprofileb
    # user profile is UserProfileB
except UserProfileB.DoesNotExist:
    # user profile wasn't either a or b...

編集:再、あなたのコメント。

リレーショナル モデルは、オブジェクト指向の哲学に反するように思われる多くのことを暗示しています。リレーションが有用であるためには、リレーション内のすべての要素が同じ次元を持つ必要があるため、リレーショナル クエリはリレーション全体に対して有効です。これはアプリオリに知られているため、リレーションに格納されたクラスのインスタンスに遭遇する前は、行はサブクラスになることはできません。django の orm は、サブクラス情報を別のリレーション (サブクラスに固有のもの) に格納することで、このインピーダンスの不一致を克服します。他の解決策もありますが、それらはすべてリレーショナル モデルのこの基本的な性質に従います。

これを理解するのに役立つ場合は、ORM が存在しないアプリケーションで RDBM の永続性がどのように機能するかを検討することをお勧めします。特に、リレーショナル データベースは、データベースからフェッチされたデータにビヘイビアを適用するというよりも、多くの行のコレクションと要約に重点を置いています。

のプロファイル機能を使用する特定の例はdjango.contrib.auth、特にそのモデルが使用される唯一の方法が特定のdjango.contrib.auth.models.Userインスタンスに関連付けられたプロファイル データを取得することである場合は、かなり興味深いものです。他にクエリがない場合は、django.models.Modelサブクラスはまったく必要ありません。通常の python クラスをピクルして、機能のないモデルの blob フィールドに格納できます。

一方、特定の都市に住んでいるユーザーを検索するなど、プロファイルでもっと興味深いことをしたい場合は、すべてのプロファイルがその都市のプロパティのインデックスを持つことが重要になります。それは OOP とは何の関係もなく、すべてリレーショナルと関係があります。

于 2011-01-03T02:09:30.473 に答える
1

複数プロファイルの問題を解決することを目的としたPinaxチームによるidiosアプリ。モデルを微調整して、基本プロファイルクラスの継承を抽象的または非抽象的にすることができます。 https://github.com/eldarion/idios

于 2011-01-03T02:27:41.017 に答える
0

複数のプロファイルを機能させる方法についての私の質問に対する答えは次のとおりです。

from django.contrib.contenttypes.models import ContentType
class Contact(models.Model):

    content_type = models.ForeignKey(ContentType,editable=False,null=True)

    def save(self):
        if(not self.content_type):
            self.content_type = ContentType.objects.get_for_model(self.__class__)
        self.save_base()

    def as_leaf_class(self):
        content_type = self.content_type
        model = content_type.model_class()
        if(model == Contact):
            return self
        return model.objects.get(id=self.id)

なぜそれが機能するのか、またはdjango/pythonの開発者が継承をこのように機能させたのかはよくわかりません

于 2011-01-03T02:36:32.667 に答える
0

ユーザーごとにアプリ固有のオプションがある場合は、別のモデルに入れることをお勧めします。

簡単な例:

class UserSettings(models.Model):
    user = models.ForeignKey(User, primary_key = True)

    # Settings go here
    defaultLocale = models.CharField(max_length = 80, default = "en_US")
    ...

これは次のように使用されます。

def getUserSettings(request):
    try:
        return UserSettings.objects.get(pk = request.user)
    except UserSettings.DoesNotExist:
        # Use defaults instead, that's why you should define reasonable defaults
        # in the UserSettings model
        return UserSettings()
于 2011-01-03T15:46:01.737 に答える