【问题标题】:Foreign key needs a value from the key's table to match a column in another table外键需要键表中的值来匹配另一个表中的列
【发布时间】:2009-10-21 15:21:24
【问题描述】:

请原谅过多的代码,但我不确定是否可以用其他方式解释我的问题

我有一个正在处理的 Django 项目,其中包含以下内容:

class Project(models.Model):
    name = models.CharField(max_length=100, unique=True)
    dir  = models.CharField(max_length=300, blank=True, unique=True )

    def __unicode__(self):
        return self.name;

class ASClass(models.Model):
    name      = models.CharField(max_length=100)
    project   = models.ForeignKey(Project, default=1)

    def __unicode__(self):
        return self.name;

class Entry(models.Model):
    project     = models.ForeignKey(Project, default=1)
    asclasses   = models.ManyToManyField(ASClass)

问题来了:

有没有办法在不覆盖模型的保存功能的情况下,使条目只允许具有相同项目 ID 的类?

**************************************************** ************开始编辑************************************ ************************
需要明确的是,我并不反对压倒保存。在这种情况下,我实际上已经覆盖了它以提供上面未列出的属性。我已经知道如何通过简单地扩展该覆盖来回答这个问题,所以简单地说“你可以覆盖保存”是没有帮助的。

我想知道是否没有更好的方法来实现这一点,是否有 Django 本地实现,以及密钥类型是否已经存在。

**************************************************** ************结束编辑************************************ ***********************

在 Postgresql 中也有办法做到这一点吗?

(为了更好的衡量,这里是在 Postgresql 中创建表的代码) 这创建了以下表格:

CREATE TABLE blog_asclass
(
  id serial NOT NULL,
  "name" character varying(100) NOT NULL,
  project_id integer NOT NULL,
  CONSTRAINT blog_asclass_pkey PRIMARY KEY (id),
  CONSTRAINT blog_asclass_project_id_fkey FOREIGN KEY (project_id)
      REFERENCES blog_project (id) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION DEFERRABLE INITIALLY DEFERRED
)

CREATE TABLE blog_entry
(
  id serial NOT NULL,
  project_id integer NOT NULL,
  build_date timestamp with time zone NOT NULL,
  CONSTRAINT blog_entry_pkey PRIMARY KEY (id),
  CONSTRAINT blog_entry_project_id_fkey FOREIGN KEY (project_id)
      REFERENCES blog_project (id) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION DEFERRABLE INITIALLY DEFERRED
)

CREATE TABLE blog_entry_asclasses
(
  id serial NOT NULL,
  entry_id integer NOT NULL,
  asclass_id integer NOT NULL,
  CONSTRAINT blog_entry_asclasses_pkey PRIMARY KEY (id),
  CONSTRAINT blog_entry_asclasses_asclass_id_fkey FOREIGN KEY (asclass_id)
      REFERENCES blog_asclass (id) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION DEFERRABLE INITIALLY DEFERRED,
  CONSTRAINT blog_entry_asclasses_entry_id_fkey FOREIGN KEY (entry_id)
      REFERENCES blog_entry (id) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION DEFERRABLE INITIALLY DEFERRED,
  CONSTRAINT blog_entry_asclasses_entry_id_key UNIQUE (entry_id, asclass_id)
)

CREATE TABLE blog_project
(
  id serial NOT NULL,
  "name" character varying(100) NOT NULL,
  dir character varying(300) NOT NULL,
  CONSTRAINT blog_project_pkey PRIMARY KEY (id),
  CONSTRAINT blog_project_dir_key UNIQUE (dir),
  CONSTRAINT blog_project_name_key UNIQUE (name)
)

【问题讨论】:

    标签: python database django


    【解决方案1】:

    您可以使用pre_save 信号并在它们不匹配时引发错误...效果类似于覆盖保存(它在保存之前被调用)

    问题是创建/删除/更新多对多关系不会触发保存(或因此pre_savepost_save

    更新

    尝试使用through argument on your many-to-many relation

    这使您可以手动定义 m2m 关系的中间表,这将使您能够访问信号以及函数。

    然后你可以随意选择信号或重载

    【讨论】:

      【解决方案2】:

      我相信您可以在 PostgreSQL 级别使用 trigger 执行此操作,您可以将其添加到 Django initial-SQL file 以便它在 syncdb 中自动创建。

      在 Django 模型级别,为了获得有用的答案,您必须澄清为什么您反对覆盖 save() 方法,因为这是目前提供此方法的正确(也许是唯一)方法一种验证。

      Django 1.2 将(希望)包含full model validation framework

      【讨论】:

      • 我反对覆盖保存,因为 1. 这似乎是其他人可能已经提出解决方案的问题,甚至可能是 Django 本身和 2. 为了正确验证,我将需要遍历 asclasses 数组的每个成员以单独测试所有内容。如果有其他方法,我会更喜欢那个。
      • 还因为覆盖 save 不起作用:) 您需要检查多对多关系 - 并且创建/编辑/删除多对多关系会影响不同的(隐藏的)数据库表.不过,您可以在 m2m 上使用“通过”参数(docs.djangoproject.com/en/dev/ref/models/fields/…
      • 啊,没有仔细看模型。是的,在 M2M 上使用 through 参数是可行的方法。
      猜你喜欢
      • 2020-04-11
      • 1970-01-01
      • 2023-03-17
      • 1970-01-01
      • 1970-01-01
      • 2016-04-09
      • 2018-05-24
      • 1970-01-01
      • 2018-08-15
      相关资源
      最近更新 更多