Я делаю то, что не очень эффективно. Из моего кода ниже вы можете видеть, что я пытаюсь разрешить несколько профилей разных типов, прикрепленных к моему пользовательскому объекту пользователя (Person). Один из этих профилей будет считаться дефолтом и должен иметь аксессор из класса Person. Сохранение поля is_default
в профиле не похоже на то, что это был бы лучший способ отслеживать значение по умолчанию, не так ли?Как обрабатывать несколько профилей для каждого пользователя?
from django.db import models
from django.contrib.auth.models import User, UserManager
class Person(User):
public_name = models.CharField(max_length=24, default="Mr. T")
objects = UserManager()
def save(self):
self.set_password(self.password)
super(Person, self).save()
def _getDefaultProfile(self):
def_teacher = self.teacher_set.filter(default=True)
if def_teacher: return def_teacher[0]
def_student = self.student_set.filter(default=True)
if def_student: return def_student[0]
def_parent = self.parent_set.filter(default=True)
if def_parent: return def_parent[0]
return False
profile = property(_getDefaultProfile)
def _getProfiles(self):
# Inefficient use of QuerySet here. Tolerated because the QuerySets should be very small.
profiles = []
if self.teacher_set.count(): profiles.append(list(self.teacher_set.all()))
if self.student_set.count(): profiles.append(list(self.student_set.all()))
if self.parent_set.count(): profiles.append(list(self.parent_set.all()))
return profiles
profiles = property(_getProfiles)
class BaseProfile(models.Model):
person = models.ForeignKey(Person)
is_default = models.BooleanField(default=False)
class Meta:
abstract = True
class Teacher(BaseProfile):
user_type = models.CharField(max_length=7, default="teacher")
class Student(BaseProfile):
user_type = models.CharField(max_length=7, default="student")
class Parent(BaseProfile):
user_type = models.CharField(max_length=7, default="parent")
Я избегал удаления абстракции из BaseProfile в надежде, что вам не придется проходить через другой слой, прежде чем попасть в мои «типизированные» профили, находясь в шаблонах. Однако недостающую часть этой головоломки, которую я пропустил, это создание аксессуаров на модели, которая скрывала этот слой от шаблонов. Теперь я вижу, что на этом пути открывается множество лучших способов сделать это, и именно этого я и искал. Я буду экспериментировать с этим подходом, спасибо Киллиан! – Scott