![](/img/trans.png)
[英]Django: Force a field to be unique for all model objects with the same foreign key
[英]getting all records with same foreign key in django
我正在 Django/Postgres 中開展我的第一個項目,這是一個跟蹤植物育種項目的應用程序。 我有一個Generation
模型,它連接到一個帶有ForeignKey
的Project
模型(即,每個育種項目由多代后代組成):
class Generation(models.Model):
# ...
project = models.ForeignKey(
Project,
related_name="generations",
on_delete=models.CASCADE
)
我想添加一個generation_number
字段,該字段根據關聯的項目自動遞增 - 如果 Generation 表中已經有 3 條具有相同外鍵的記錄,那么使用該 FK 創建的下一條記錄應該被分配一個generation_number
為 4 . 我的理解是我不能使用AutoField
因為這不是主鍵,所以我試圖編寫一個方法來計算具有相同 FK 的記錄數並加 1,例如:
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 的新手,這感覺有點麻煩。 我怎樣才能讓它發揮作用?
您可以覆蓋 Generation 模型上的 save 方法,以及您想要的邏輯。
把這個放在你的模型上。
def save(self, *args, **kwargs):
# your logic
super(GeeksModel, self).save(*args, **kwargs)
您可以使用信號使您的字段保持最新狀態:
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()
測試通過:
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)
(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'...
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.