簡體   English   中英

Django中有多個配置文件?

[英]More than one profile in Django?

可以將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背景,這些東西會自動發生,我為有人不得不對此進行編碼並將其稱為“ hack”才能在python中完成而感到不安。 python沒有啟用此功能的原因嗎?

因此,您將遇到的問題是,無論您想要什么配置文件,都需要將其保存在某種數據庫中。 基本上,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的情況下RDBM的持久性如何用於應用程序。 特別是,關系數據庫更多地是關於許多行的集合和匯總,而不是將行為應用於一旦從數據庫中獲取的數據。

使用django.contrib.auth的配置文件功能的特定示例是一個很有趣的示例,尤其是如果曾經使用該模型的唯一方法是獲取與特定django.contrib.auth.models.User實例相關聯的配置文件數據的話。 如果沒有其他查詢,則根本不需要django.models.Model子類。 您可以腌制一個常規的python類,並將其存儲在其他沒有特征的模型的blob字段中。

另一方面,如果您想使用個人資料做更多有趣的事情,例如搜索居住在特定城市中的用戶,那么對於所有個人資料來說,為其城市屬性建立索引將非常重要。 這與OOP無關,而與關系無關。

Pinax團隊開發的idios應用旨在解決多配置文件問題。 您可以調整模型以使基本概要文件類的繼承是抽象的或非抽象的。 https://github.com/eldarion/idios

這是我有關如何使多個配置文件工作的問題的答案:

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的開發人員以這種方式使繼承起作用

如果您為每個用戶提供特定於應用程序的選項,則建議您將它們放在單獨的模型中。

一個簡化的例子:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM