【问题标题】:Django models - auto-increment id for elements of a child table for each parent referenceDjango模型-每个父引用的子表元素的自动增量ID
【发布时间】:2018-12-16 23:31:11
【问题描述】:

我正在尝试在 Django 中构建一个包含公司和项目的应用程序的数据库。每个公司可以有很多项目,每个项目只属于一个公司。

class Company(models.Model):
    name = models.CharField(max_length=20)

class Project(models.Model):
    company = models.ForeignKey(Company, on_delete=models.CASCADE)
    project_id = models.PositiveIntegerField()
    name = models.CharField(max_length=20)

我想在模型 Project 中有一个字段或属性,它就像公司内项目的自动增量整数一样。行为应如下所示:

c1 = Company(name="C1")
c2 = Company(name="C2")
px = Project(company=c1, name="X")
py = Project(company=c2, name="Y")
pz = Project(company=c1, name="Z")
px.project_id
1
py.project_id
1
pz.project_id
2

什么是正确的方法?

【问题讨论】:

  • project_id 是个坏主意,会让人感到困惑。您可以使用将对象id 与某种字符串组合在一起的属性吗?还是只使用Projectid

标签: django model auto-increment


【解决方案1】:

实现此目的最自动化的方法是自定义模型的 save 方法,例如:

class Project(models.Model):
    company = models.ForeignKey(Company, on_delete=models.CASCADE)
    project_id = models.PositiveIntegerField()
    name = models.CharField(max_length=20)

    def save(self, *args, **kwargs):
        if self.pk == None:
            self.project_id = Project.objects \ 
                .filter(company=self.company) \
                .aggregate(max_id=Max("project_id")).get("max_id",0) + 1)

        super().save(*args, **kwargs)  # Call the "real" save() method.

您可以在django docsin this blog post by Lincoln Loop 中阅读有关save 的更多信息

话虽如此,正如@markwalker_ 所指出的,您可能会发现使用辅助“id”来管理您的项目有点令人困惑,因为您已经获得了一个对所有项目都是独一无二的自然顺序的。使用 slug 和 start_date 来识别您的项目可能是值得的,然后您可以结合公司 slug 轻松识别它们、创建自然 url 等。

例如:

/company/acme-inc/2018/12/website-redesign/

对比

/company/acme-inc/project/4/

【讨论】:

  • 感谢@Nikolaj Baer,这正是我想要的。这个想法是在公司内拥有项目的“internal_id”,这样每个公司都可以轻松跟踪自己的项目。
【解决方案2】:

您可以使用 AutoField 进行自动递增:

class Project(models.Model):
    company = models.ForeignKey(Company, on_delete=models.CASCADE)
    project_id = models.AutoField(primary_key=False) # set it as primary key if you want it to be
    name = models.CharField(max_length=20)

我有点不清楚您到底要做什么,但您似乎想跟踪每家公司有多少项目。在这种情况下,您可以为 Company 编写一个模型函数来跟踪有多少:

class Company(models.Model):
    name = models.CharField(max_length=20)
    projects = models.PositiveIntegerField()

    def get_project_count(self):
        project_count = Project.objects.filter(company=self).count()
        self.projects = project_count
        self.save()
        return self.projects

【讨论】:

    猜你喜欢
    • 2019-09-09
    • 2013-05-31
    • 2012-11-04
    • 1970-01-01
    • 2016-02-28
    • 2015-01-01
    • 2020-10-15
    • 2022-11-15
    • 1970-01-01
    相关资源
    最近更新 更多