Модели Django - идентификатор автоинкремента для элементов дочерней таблицы для каждой родительской ссылки - PullRequest
0 голосов
/ 17 декабря 2018

Я пытаюсь структурировать базу данных приложения в 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)

Я хотел бы иметь поле или свойство в модельном проекте, которое действует как целое число с автоинкрементом для проектов внутри компании.Поведение должно быть следующим:

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

Каков будет правильный подход?

Ответы [ 2 ]

0 голосов
/ 17 декабря 2018

Самый автоматический способ сделать это - настроить 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.

Подробнее о save можно прочитать в документах django и в этом сообщении от Lincoln Loop

При этом, как отмечает @markwalker_, вы можете посчитать, что управлять своими проектами с помощью вторичного «id» может быть немного странно,учитывая, что вы уже получаете естественный последовательный, который уникален для всех проектов.Возможно, стоит идентифицировать ваши проекты с помощью slug и start_date, а затем вы можете легко идентифицировать их, создавать естественные URL и т. Д. В сочетании с слагом компании.

Например:

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

против

/company/acme-inc/project/4/
0 голосов
/ 17 декабря 2018

Вы можете использовать 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)

Мне немного неясно, что именно вы хотите сделать, но похоже, что вы хотите отслеживать, сколько проектовкаждая компания имеет.В этом случае вы можете написать модель функции для компании, которая отслеживает, сколько:

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...