2011-01-03 7 views
0

複数のプロファイルでDjangoのユーザ認証機能を使用することはできますか?Djangoに複数のプロフィールがありますか?

現在、私はそれでこれを持っているsettings.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) 

その方法:

AUTH_PROFILE_MODULE = 'auth.UserProfileA' 

とそれにこれを持っているmodels.pyファイルをログインすると、ユーザーにget_profile()メソッドがあるので、簡単にプロファイルを取得できます。しかし、私はUserProfileBを追加したいと思います。ちょっと見てみると、AUTH_PROFILE_MODULEとして使用するスーパークラスを作成し、そのスーパークラスからUserProfileAとUserProfileBの両方を継承することが出発点であるようです。問題は、get_profile()メソッドが正しいプロファイルを返すとは思わないということです。スーパークラスのインスタンスを返します。私はJavaのバックグラウンド(多型性)から来ているので、何をすべきか正確には分かりません。

ありがとうございます!

編集:

まあ、私はそれが本当によく、しかし、Javaの背景どこから来た作品このサイトhttp://djangosnippets.org/snippets/1031/

で発見「継承ハック」と呼ばれるものを経由して、それを行う方法を見つけましたこのことは自動的に起こります。私は、誰かがこれをコード化し、Pythonでそれを行うための "ハック"と呼ばなければならないという事実によって、少し不安です。なぜPythonがこれを有効にしないのでしょうか?

答えて

0

が動作する複数のプロファイルを取得する方法の私の質問への答えである:それが動作するか、なぜジャンゴ/のpythonの開発者が継承作業をこのように作られた理由

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) 

私は本当に理解していない

+0

私は同じ問題があります。私はちょうどあなたがあなたの 'AUTH_PROFILE_MODULE'をどこに置きましたかと思っています。 – Modelesq

4

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

Djangoはあなたが記載されている技術を使用して、多型の方法で、合理的な結果を得ることができますinheritance.ためのいくつかのサポートを提供します。

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

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... 

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

リレーショナルモデルは、オブジェクト指向の考え方とseem to disagree多くのことを意味します。関係が有用であるためには、関係のすべての要素が同じ次元を持つことが必要であり、リレーショナル照会は関係全体に対して有効である必要があります。リレーションに格納されているクラスのインスタンスに出会う前にこれが先験的にわかっているので、その行はサブクラスにはなりません。 djangoのOrmは、サブクラス情報を異なる関係(サブクラスに固有のもの)に格納することでこのインピーダンスの不一致を克服します。他の解決策もありますが、それらはすべてリレーショナルモデルのこの基本的性質に従います。

それはあなたがこれと折り合いをつけることができます場合、私は、RDBMS上の持続性はORMの不在下でのアプリケーションのためにどのように機能するかを見てお勧めしたいです。特に、リレーショナル・データベースは、データベースから一度フェッチされたデータに動作を適用するのではなく、多くの行の集まりと要約に関するものです。

django.contrib.authのプロファイル機能を使用する具体的な例は、特定のdjango.contrib.auth.models.Userインスタンスに関連付けられたプロファイルデータをフェッチすることが、そのモデルを使用する唯一の方法である場合は特に重要ではありません。他のクエリがない場合、django.models.Modelサブクラスはまったく必要ありません。通常のPythonクラスをpickleし、それ以外のフィーチャーレスモデルのblobフィールドに格納することができます。

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

+0

。私はむしろdjangosnippets.comのメソッドを使って、元の質問に編集したリンクを投稿しました。私は助けに感謝します。継承に投稿したリンクを読んだら、djangoは自動的にその子クラスが何であるかを知ることができないようです。 – JPC

1

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

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() 
関連する問題