gpt4 book ai didi

django - Django 中非常独立的数据库中的 "Foreign Keys"

转载 作者:行者123 更新时间:2023-12-02 01:59:33 25 4
gpt4 key购买 nike

我正在编写一个使用两个不同数据库的 Django 网站。一个是本地数据库,我们称之为“Django”,它存储来自相当标准安装的所有标准表——身份验证、站点、评论等——以及一些额外的表。

大多数数据(包括用户)来自另一台服务器上的数据库,我们将其称为“旧版”数据库。

我正在寻找有关连接两个数据库的干净、Pythonic 方式的建议,尤其对于用户而言。

我正在使用代理模型,当我可以显式使用它时它效果很好,但是当我将用户对象作为相关对象访问时(例如,使用内置的 django 注释时),我遇到了问题系统)。

代码如下:

models.py:(指向Django数据库)

from django.db import models
from django.conf import settings
from django.contrib.auth.models import User as AuthUser, UserManager as AuthUserManager, AnonymousUser as AuthAnonymousUser

class UserPerson(models.Model):
user = models.OneToOneField(AuthUser, related_name="person")
person_id = models.PositiveIntegerField(verbose_name='Legacy ID')

def __unicode__(self):
return "%s" % self.get_person()

def get_person(self):
if not hasattr(self, '_person'):
from legacy_models import Person
from utils import get_person_model
Person = get_person_model() or Person
self._person = Person.objects.get(pk=self.person_id)
return self._person
person=property(get_person)

class UserManager(AuthUserManager):
def get_for_id(self, id):
return self.get(person__person_id=id)

def get_for_email(self, email):
try:
person = Person.objects.get(email=email)
return self.get_for_id(person.pk)
except Person.DoesNotExist:
return User.DoesNotExist

def create_user(self, username, email, password=None, *args, **kwargs):
user = super(UserManager,self).create_user(username, email, password, *args, **kwargs)
try:
person_id = Person.objects.get(email=email).pk
userperson, created = UserPerson.objects.get_or_create(user=user, person_id=person_id)
except Person.DoesNotExist:
pass
return user

class AnonymousUser(AuthAnonymousUser):
class Meta:
proxy = True

class User(AuthUser):
class Meta:
proxy=True

def get_profile(self):
"""
Returns the Person record from the legacy database
"""
if not hasattr(self, '_profile_cache'):
self._profile_cache = UserPerson.objects.get(user=self).person
return self._profile_cache

objects = UserManager()

legacy_models.py:(指向“Legacy”数据库)

class Person(models.Model):
id = models.AutoField(primary_key=True, db_column='PeopleID') # Field name made lowercase.
code = models.CharField(max_length=40, blank=True, db_column="person_code", unique=True)
first_name = models.CharField(max_length=50, db_column='firstName', blank=True) # Field name made lowercase.
last_name = models.CharField(max_length=50, db_column='lastName', blank=True) # Field name made lowercase.
email = models.CharField(max_length=255, blank=True)

def __unicode__(self):
return "%s %s" % (self.first_name, self.last_name)

def get_user(self):
from models import User
if not hasattr(self,'_user'):
self._user = User.objects.get_for_id(self.pk)
return self._user
user = property(get_user)

class Meta:
db_table = u'People'

我还创建了自己的中间件,因此 request.user 也是代理 User 对象。

真正的问题是当我使用将用户作为相关对象的东西时,特别是在我控制权更少的模板中。

在模板中:

{{ request.user.get_profile }} 
{# this works and returns the related Person object for the user #}

{% for comment in comments %} {# retrieved using the built-in comments app %}
{{ comment.user.get_profile }}
{# this throws an error because AUTH_PROFILE_MODULE is not defined by design #}
{% endfor %}

除了创建使用我的代理用户模型的评论系统的包装版本之外,我还能做些什么吗?

最佳答案

这是我解决这个问题的方法。我完全停止使用用户代理。

models.py:

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

class UserPerson(models.Model):
user = models.OneToOneField(User, related_name="person")
person_id = models.PositiveIntegerField(verbose_name='PeopleID', help_text='ID in the Legacy Login system.')

def __unicode__(self):
return "%s" % self.get_person()

def get_person(self):
if not hasattr(self, '_person'):
self._person = Person.objects.get(pk=self.person_id)
return self._person
person=property(get_person)

class LegacyPersonQuerySet(models.query.QuerySet):
def get(self, *args, **kwargs):
person_id = UserPerson.objects.get(*args, **kwargs).person_id
return LegacyPerson.objects.get(pk=person_id)

class LegacyPersonManager(models.Manager):
def get_query_set(self, *args, **kwargs):
return LegacyPersonQuerySet(*args, **kwargs)

class LegacyPerson(Person):
objects = LegacyPersonManager()

class Meta:
proxy=True

legacy_models.py:

class Person(models.Model):
id = models.AutoField(primary_key=True, db_column='PeopleID') # Field name made lowercase.
code = models.CharField(max_length=40, blank=True, db_column="person_code", unique=True)
first_name = models.CharField(max_length=50, db_column='firstName', blank=True) # Field name made lowercase.
last_name = models.CharField(max_length=50, db_column='lastName', blank=True) # Field name made lowercase.
email = models.CharField(max_length=255, blank=True)

def __unicode__(self):
return "%s %s" % (self.first_name, self.last_name)

def get_user(self):
from models import User
if not hasattr(self,'_user'):
self._user = User.objects.get_for_id(self.pk)
return self._user
def set_user(self, user=None):
self._user=user
user = property(get_user, set_user)

class Meta:
db_table = u'People'

最后,在settings.py中:

AUTH_PROFILE_MODULE = 'myauth.LegacyPerson'

这是一个更简单的解决方案,但至少它有效!这确实意味着每当我想要旧记录时,我都必须调用 user_profile,这意味着每个用户记录都有一个额外的查询,但这是一个公平的权衡,因为实际上它不是我很可能会经常进行交叉检查。

关于django - Django 中非常独立的数据库中的 "Foreign Keys",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4632049/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com