首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在django中获取具有相同外键的所有记录

在django中获取具有相同外键的所有记录
EN

Stack Overflow用户
提问于 2021-07-18 05:29:30
回答 2查看 55关注 0票数 1

我正在做我的第一个项目Django/Postgres,这是一个追踪植物育种项目的应用程序。我有一个Generation模型,它使用ForeignKey连接到Project模型(即,每个育种项目由多代后代组成):

代码语言:javascript
复制
class Generation(models.Model):
   # ...
   project = models.ForeignKey(
     Project, 
     related_name="generations", 
     on_delete=models.CASCADE
     )

我想添加一个根据相关项目自动递增的generation_number字段-如果在生成表中已经有3条记录具有相同的外键,那么使用该FK创建的下一条记录应该被分配generation_number为4。我的理解是我不能使用AutoField,因为这不是主键,所以我正在尝试编写一个方法来计算具有相同FK的记录的数量并加1,类似于:

代码语言:javascript
复制
def increment_gen_number(self):
  last_count = Project.objects.filter(pk=self.project).count()
  return last_count+1

gen_number = models.IntegerField(default=increment_gen_number)

我猜有一些语法问题,因为我仍然是Python的新手,这感觉有点杂乱无章。我怎么才能让它工作呢?

EN

回答 2

Stack Overflow用户

发布于 2021-07-18 06:52:45

您可以重写Generation模型上的save方法,也可以重写所需的逻辑。

把这个放到你的模型上。

代码语言:javascript
复制
def save(self, *args, **kwargs):
    # your logic
    super(GeeksModel, self).save(*args, **kwargs)
票数 0
EN

Stack Overflow用户

发布于 2021-07-20 15:55:06

您可以使用信号使字段保持最新:

代码语言:javascript
复制
from django.db import models

class Project(models.Model):   
   n_generations = models.IntegerField(default=0)


class Generation(models.Model):
   project = models.ForeignKey(
     Project, 
     related_name="generations", 
     on_delete=models.CASCADE
     )

# Signals
from django.db.models.signals import post_save, post_delete
from django.dispatch import receiver
from django.db.models import F


@receiver(post_save, sender=Generation)
def add_project(sender, instance, created, **kwargs):
    if not created:
        return
    project = instance.project
    project.n_generations = F('n_generations') + 1
    project.save()
    project.refresh_from_db()

@receiver(post_delete, sender=Generation)
def rm_project(sender, instance, **kwargs):
    project = instance.project
    project.n_generations = F('n_generations') - 1
    project.save()
    project.refresh_from_db()

测试通过:

代码语言:javascript
复制
from django.test import TestCase
from ppapp.models import Project, Generation

class ProjectTestCase(TestCase):
    def setUp(self):
        Project.objects.create()

    def test_animals_can_speak(self):
        """Animals that can speak are correctly identified"""
        p1 = Project.objects.all()[0]

        g1 = Generation(project=p1) # +1
        g1.save()
        g2 = Generation(project=p1) # +1
        g2.save()
        g3 = Generation(project=p1) # +1
        g3.save()
        g4 = Generation(project=p1) # +1
        g4.save()
        p1.generations.create() # +1
        g6 = Generation(project=p1) # +1
        g6.save()
        g6.delete() # -1
        
        self.assertEqual(p1.n_generations, 5)
代码语言:javascript
复制
(venv) dani@localhost ppp $ ./manage.py test
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
.
----------------------------------------------------------------------
Ran 1 test in 0.017s

OK
Destroying test database for alias 'default'...
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68424408

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档