Django中的循环DB关系
我有以下模型(活动/models.py) …这导致了以下数据库(sqlite3): 逻辑如下:Django中的循环DB关系,django,database,relationship,circular-dependency,Django,Database,Relationship,Circular Dependency,我有以下模型(活动/models.py) …这导致了以下数据库(sqlite3): 逻辑如下: 活动由测试组成 一个活动可以运行多次(活动运行)并产生测试结果(测试运行) 对于每个活动运行,将从测试表中收集与测试相关的信息 显然,存在循环关系,数据库的完整性仅由应用程序来保证 但是,从数据库架构师的角度来看,这种循环关系是不正确的,因为它会导致完整性问题: 在SQL中直接或通过django管理模块,可以在campaign_testrun中创建不在campaign_tests表中的测试 出
- 活动由测试组成
- 一个活动可以运行多次(活动运行)并产生测试结果(测试运行)
- 对于每个活动运行,将从测试表中收集与测试相关的信息
- 在SQL中直接或通过django管理模块,可以在campaign_testrun中创建不在campaign_tests表中的测试
出于上述原因,解决方案是将活动\u testrun与活动\u活动\u测试直接链接。然而,我认为在Django是不可能的 如果您有任何想法如何处理这个问题,欢迎发表评论 提前感谢您的帮助。使用ManyToManyField 这允许您使用自定义模型,并在FKs、M2M等中引用它 还要注意的是,您可以引用类名,即ForeignKey('SomeClass'),这样可以毫无问题地实现循环关系 欢迎来到Django,祝您旅途愉快B)使用ManyToManyField 这允许您使用自定义模型,并在FKs、M2M等中引用它 还要注意的是,您可以引用类名,即ForeignKey('SomeClass'),这样可以毫无问题地实现循环关系
欢迎来到Django,祝你旅途愉快B)“但是,我认为在Django不可能。”为什么?您尝试了什么?与以下问题无关:您是如何获得数据库布局的出色表示的?@clentford:我使用textedit手动完成了此DB表示:P@jpic:为什么?因为理想的方法是与campaigns_campaign_tests Manytomy表建立关系,这在Django中似乎不可能,对吧?我试了什么?我的问题中指定的模型:)“但是,我认为在Django不可能。”为什么?您尝试了什么?与以下问题无关:您是如何获得数据库布局的出色表示的?@clentford:我使用textedit手动完成了此DB表示:P@jpic:为什么?因为理想的方法是与campaigns_campaign_tests Manytomy表建立关系,这在Django中似乎不可能,对吧?我试了什么?我的问题中指定的模型:)
from django.db import models
from django.contrib.auth.models import User
class Module(models.Model):
name = models.CharField(max_length=20)
def __unicode__(self):
return self.name
class TestType(models.Model):
name = models.CharField(max_length=20)
def __unicode__(self):
return self.name
class Test(models.Model):
PROTO_CHOICES = (
('TCP','tcp'),
('UDP','udp'),
)
module = models.ForeignKey(Module)
testtype = models.ForeignKey(TestType)
name = models.CharField(max_length=50, unique=True)
port = models.IntegerField(blank=True, null=True)
proto = models.CharField(max_length=3, blank=True, choices=PROTO_CHOICES)
payload = models.TextField()
sig_match = models.TextField(blank=True)
def __unicode__(self):
return self.name
class Campaign(models.Model):
name = models.CharField(max_length=50, unique=True)
tests = models.ManyToManyField(Test)
updated = models.DateTimeField(auto_now_add=True)
user = models.ForeignKey(User, editable=False)
def __unicode__(self):
return self.name
class CampaignRun(models.Model):
campaign = models.ForeignKey(Campaign)
name = models.CharField(max_length=50, unique=True)
run_start = models.DateTimeField()
run_end = models.DateTimeField()
updated = models.DateTimeField(auto_now=True)
user = models.ForeignKey(User, editable=False)
class Meta:
def __unicode__(self):
return self.name
class TestRun(models.Model):
campaignrun = models.ForeignKey(CampaignRun)
test = models.ForeignKey(Test)
test_start = models.DateTimeField()
test_end = models.DateTimeField()
alert = models.TextField(blank=True)
flag = models.IntegerField(blank=True, null=True)
+-----------------------------+
| |
+---------------------------+ +------------------------------+ | +--------------------+ |
| campaigns_testrun | | campaigns_test | | | campaigns_module | |
+----------------+----------+ +----------------+-------------+ | +------+-------------+ |
| id | INT | +--| id | INT |--+ +--| id | INT | |
+--| campaignrun_id | INT | | | module_id | INT |-----+ | name | VARCHAR(20) | |
| | test_id | INT |--+ | testtype_id | INT |--+ +------+-------------+ |
| | test_start | DATETIME | | name | VARCHAR(50) | | |
| | test_end | DATETIME | | port | INT | | +--------------------+ |
| | alert | TEXT | | proto | VARCHAR(3) | | | campaigns_testtype | |
| | flag | INT | | payload | TEXT | | +------+-------------+ |
| +----------------+----------+ | sig_match | TEXT | +-----| id | INT | |
| +----------------+-------------+ | name | VARCHAR(20) | |
| +------+-------------+ |
| |
| +------------------------+ +--------------------------+ |
| | campaigns_campaignrun | +--------------------+ | campaigns_campaign_tests | |
| +-------------+----------+ | campaigns_campaign | +-------------+------------+ |
+--| id | INT | +------+-------------+ | id | INT | |
| campaign_id | INT |-----| id | INT |-----| campaign_id | INT | |
| name | INT | | name | VARCHAR(50) | | test_id | INT |------------+
| run_start | DATETIME | +------+-------------+ +-------------+------------+
| run_end | DATETIME |
+-------------+----------+