在Django Admin中为一个控件使用两个数据库表

时间:2014-01-23 15:30:32

标签: django python-2.7

我正在创建一个小应用程序,以帮助我们的培训部门使用Django管理他们的课程。当我们谈论学生时,我们有两种类型;员工和客户。

由于所有员工都在auth_user,我宁愿不必填充另一个包含该数据的表。我想要的行为是在Django Admin中显示一个Class时我希望一个控件填充来自学生列表的两个表的数据。这在Django中是否可行。我怀疑它不是。这就是我正在搞乱的地方:

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

class Student(models.Model):
    cell_phone = models.CharField(max_length=14)

    class Meta:
        abstract = True

class EmployeeStudent(models.Model, Student):
    user = models.OneToOneField(User)
    extension = models.CharField(max_length=4, null=True, blank=True, default=None)

class CustomerStudent(models.Model, Student):
    first_name = models.CharField(max_length=25)
    last_name = models.CharField(max_length=25)
    email = models.CharField(max_length=25)

但是,只要考虑它就可以了:

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

class Student(models.Model):
    user = models.ForeignKey(User, null=True, blank=True, default=None)
    first_name = models.CharField(max_length=25, null=True, blank=True, default=None)
    last_name = models.CharField(max_length=25, null=True, blank=True, default=None)
    email = models.CharField(max_length=25, null=True, blank=True, default=None)
    extension = models.CharField(max_length=4, null=True, blank=True, default=None)

我想到一张空白的记录时感到畏缩。

有什么建议吗?将所有内容添加到auth_user并将staff标志保留为false然后只使用一对一字段将auth_user映射到学生是否有意义?如果我不需要,我真的不想这样做因为我不打算让任何其他人访问auth_user表,所以我需要对这个表添加所有内容。

2 个答案:

答案 0 :(得分:1)

您可以尝试为您的Student模型使用模型继承(即用户模型继承:https://docs.djangoproject.com/en/dev/topics/auth/customizing/#extending-user),或者在EmployeeStudent和CustomerStudent模型中将Student(models.Model)与User混合使用:

class Student(models.Model):
    cell_phone = models.CharField(max_length=14)

    class Meta:
        abstract = True

class EmployeeStudent(User, Student):
    user = models.OneToOneField(User)
    extension = models.CharField(max_length=4, null=True, blank=True, default=None)

class CustomerStudent(User, Student):
    first_name = models.CharField(max_length=25)
    last_name = models.CharField(max_length=25)
    email = models.CharField(max_length=25)

或:

class Student(User):
    cell_phone = models.CharField(max_length=14)

    class Meta:
        abstract = True

class EmployeeStudent(models.Model):
    user = models.OneToOneField(Student)
    extension = models.CharField(max_length=4, null=True, blank=True, default=None)

class CustomerStudent(models.Model):
    first_name = models.CharField(max_length=25)
    last_name = models.CharField(max_length=25)
    email = models.CharField(max_length=25)

如果我理解正确,那么您是否希望在管理员的同一个更改列表中显示客户和员工?使用Student(User)和Employee / Customer作为内联可以解决您的问题。

希望这有帮助,

此致

答案 1 :(得分:1)

这是Django中相当常见的用例(即不同类型的用户配置文件)。在您的情况下,我认为以下方法适合您的情况:

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

class Student(models.Model):
    STUDENT_TYPES = (
        ('E', 'EmployeeStudent'),
        ('C', 'CustomerStudent'),
    )
    user = models.OneToOneField(User, null=True, blank=True, default=None)
    user_type = models.CharField(max_length=1, choices=STUDENT_TYPES)

class EmployeeDetails(models.Model):
    student = models.OneToOneField(Student)
    extension = models.CharField(max_length=4, null=True, blank=True, default=None)


class StudentDetails(models.Model):
    student = models.OneToOneField(Student)
    # BTW: all the fields below are redundant since they are already in User
    first_name = models.CharField(max_length=25, null=True, blank=True, default=None)
    last_name = models.CharField(max_length=25, null=True, blank=True, default=None)
    email = models.CharField(max_length=25, null=True, blank=True, default=None)

这样,您可以查看student.user_type并推断您是否需要EmployeeDetailsStudentDetails

注意::尽管这是推荐的方法,但以这种方式使用默认管理界面输入数据并不容易。您可能希望了解profile inlines如何完成以显示管理员中的用户个人资料字段。