开发者

Foreign key needs a value from the key's table to match a column in another table

Pardon the excessive amount of code, but I'm not sure if I can explain my question otherwise

I have a Django project that I am working on which has the following:

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)

Here's the question:

Is there a way, without overriding the save function of the model, to make it so that entries only allow classes which have the same project ID?

***********************************************************Begin Edit**********************************************************

To be clear, I am not opposed to overriding save. I actually already overrode it in this case to provide for a property not listed above. I already know how to answer this question by simply extending that override, so simply saying, "You could override save" won't be helpful.

I'm wonderin开发者_如何转开发g if there isn't a better way to accomplish this, if there is a Django native implementation, and if the key type already exists.

***********************************************************End Edit***********************************************************

Is there a way to do this in Postgresql as well?

(For good measure, here is the code to create the tables in the Postgresql) This has created the following tables:

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)
)


You could use the pre_save signal and raise an error if they do no match... The effect would be similar to overridding save (it gets called before save)

The problem is creating/deleting/updating the many-to-many relation will not trigger save (or consequentially pre_save or post_save)

Update

Try using the through argument on your many-to-many relation

That lets you manually define the intermediary table for the m2m relation, which will give you access to the signals, as well as the functions.

Then you can choose signals or overloading as you please


I'm sure you could do it at the PostgreSQL level with a trigger, which you could add to a Django initial-SQL file so it's automatically created at syncdb.

At the Django model level, in order to get a useful answer you'll have to clarify why you're opposed to overriding the save() method, since that is currently the correct (and perhaps only) way to provide this kind of validation.

Django 1.2 will (hopefully) include a full model validation framework.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜