J'ai écrit un site Django qui utilise deux bases de données différentes. L'un est local, appelons-le, "Django", base de données qui stocke toutes les tables standard à partir d'une installation standard assez simple - auth, sites, commentaires, etc. - plus quelques tables supplémentaires."Clés étrangères" à travers des bases de données très distinctes dans Django
La plupart des données, y compris les utilisateurs, proviennent d'une base de données sur un autre serveur, appelons-la la base de données "Legacy".
Je suis à la recherche de suggestions sur les façons propres et pythoniques de la connexion des deux bases de données, en particulier en ce qui concerne les utilisateurs. J'utilise un modèle de proxy, qui fonctionne très bien quand je peux l'utiliser explicitement, mais je rencontre des problèmes lorsque j'accède à l'objet utilisateur en tant qu'objet associé (par exemple, lorsque j'utilise le django intégré système de commentaires).
Voici ce que le code ressemble à:
models.py: (points à la base de données 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: (points à la base de données "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'
J'ai aussi fouetté mon propre middleware, donc request.user
est le pr oxy User
objet aussi.
Le vrai problème est quand j'utilise quelque chose qui a l'utilisateur comme un objet connexe, en particulier dans un modèle où j'ai encore moins de contrôle.
Dans le modèle:
{{ 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 %}
Court de créer une version enveloppée du système de commentaires qui utilise mon proxy modèle de l'utilisateur à la place, est-il autre chose que je peux faire?