I have a Foreign key that relates to self
class Fok(models.Model):
name = models.TextField(max_length=50)
fok = models.ForeignKey('self', related_name='foks')
trying to create a first instance of this class ending up with an error: fok.fok_id can not be NULL.
Where do I mistake? What should I do?
Your first instance doesn't have a related fok, therefore you must allow null values in this relation.
fok = models.ForeignKey('self', related_name='foks', null=True)
I know that normally Django would create a foreign key called user_id if I simply do something like
from django.db import models
class Order(models.Model):
user = models.ForeignKey(User)
comments = models.CharField(max_length=400)
date_created = models.DateTimeField('created date')
class User(models.Model):
name = models.CharField(max_length=200)
age = models.IntegerField()
but what if I need three distinct foreign key in Order that all points to User? The three foreign keys would be user_created, user_modified, and user_status.
The solution is actually straight forward:
class Order(models.Model):
user_status = models.ForeignKey(User, related_name='orders_status')
user_created = models.ForeignKey(User, related_name='orders_created')
user_modified = models.ForeignKey(User, related_name='orders_modified')
You just need to define separate related_names to avoid ambiguity when accessing the Order from the User object.
I am connecting Castle ActiveRecord to a legacy database and I am having trouble wiring up a One-To-Many relationship. The problem is that the foreign key does not reference the primary key of the other table, it uses another column.
These are the tables (shortened for clarity):
CREATE TABLE [Rule](
[ID] [uniqueidentifier] NOT NULL,
[HeadingID] [int] NULL
)
CREATE TABLE [Heading](
[ID] [uniqueidentifier] NOT NULL,
[ID2] [int] NOT NULL
)
The HeadingID field in the Rule table is a foreign key which references the ID2 field in Heading.
So, in the definition of the Rule class I have:
[BelongsTo(Column = "HeadingID", PropertyRef = "OrderID")]
public virtual Heading Heading { get; set; }
This seems to work fine, I can access the Heading of a Rule with no problem (if I set the HasMany lazy of course).
In the Heading class definition I have:
[HasMany(Lazy = true)]
public IList<Rule> Rules { get; set; }
When I access the collection I get an SQL exception "Operand type clash: uniqueidentifier is incompatible with int."
It looks like AR is attempting to do a select like this (simplified for clarity):
SELECT ... FROM Rule rules0_ ... WHERE rules0_.HeadingID = ?
Where ? is the GUID from Heading.ID (it should be the int from Heading.ID2).
I can't find a property for HasMany that allows me to set the column to which the foreign key refers. Is there any way to do this?
It appears that this cannot be done. The best I could do was a custom find:
public virtual IEnumerable<Rule> Rules {
get {
return Rule.Queryable.Where(x => x.Heading == this);
}
}
This works well enough for me.
I am creating a communication module with email and onsite messaging. 4 questions:
1) When storing the messages, it can belong to folders (Spam, trash, inbox, outbox, etc). Are these separate tables or 1 table with just a column for "folder" which is FK to a "folder lookup table"?
2) Like on hotmail, a user can create x number of custom folders so how to represent that in the data model? I can say inbox = id 1, outbox = id 2, etc but for the custom folders like "vacation email", "work email", etc i am not sure how to show that in the Data model if a message resides in that folder.
3) One email goes to multiple people. Does this mean i need to have 1 row per user sent to?
4) Lastly, messages have attachments. i assume that means a separate attachments table which FK links to which ever table (s) are used for storing messages?
1&2: Folders need to be an entity, relationship MessageFolder one to many to Message
3: MessageUser entity with UserID, MessageID, Type (Sender,Recipient)
4: Seperate table for attachments (MessageAttachments).
CREATE TABLE `message`
(
`id` INTEGER NOT NULL AUTO_INCREMENT,
`author` INTEGER NOT NULL,
`contents` TEXT NOT NULL,
`subject` TEXT NOT NULL,
PRIMARY KEY (`id`)
);
CREATE TABLE `messagefolder`
(
`id` INTEGER NOT NULL AUTO_INCREMENT,
`id_message` INTEGER NOT NULL,
`id_folder` INTEGER NOT NULL,
PRIMARY KEY (`id`)
);
CREATE TABLE `folder`
(
`id` INTEGER NOT NULL AUTO_INCREMENT,
`name` VARCHAR(200) NOT NULL,
PRIMARY KEY (`id`)
);
CREATE TABLE `messageattachment`
(
`id` INTEGER NOT NULL AUTO_INCREMENT,
`fk_message` INTEGER NOT NULL,
PRIMARY KEY (`id`)
);
CREATE TABLE `user`
(
`id` INTEGER NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`)
);
CREATE TABLE `messageuser`
(
`id` INTEGER NOT NULL AUTO_INCREMENT,
`fk_message` INTEGER NOT NULL,
`type` INTEGER NOT NULL,
PRIMARY KEY (`id`)
);;
ALTER TABLE `message` ADD FOREIGN KEY (author) REFERENCES `user` (`id`);
ALTER TABLE `messagefolder` ADD FOREIGN KEY (id_message) REFERENCES `message` (`id`);
ALTER TABLE `messagefolder` ADD FOREIGN KEY (id_folder) REFERENCES `folder` (`id`);
ALTER TABLE `messageattachment` ADD FOREIGN KEY (fk_message) REFERENCES `message` (`id`);
ALTER TABLE `messageuser` ADD FOREIGN KEY (fk_message) REFERENCES `message` (`id`);
1) When storing the messages, it can belong to folders (Spam, trash,
inbox, outbox, etc). Are these separate tables or 1 table with just a
column for "folder" which is FK to a "folder lookup table"?
One folder can have many messages. If a message can reside in one folder only, then the relations is one (folder) to many (messages), so yes to the 2nd choice.
First choice is leads to a not normalized database.
2) Like on hotmail, a user can create x number of custom folders so
how to represent that in the data model? I can say inbox = id 1,
outbox = id 2, etc but for the custom folders like "vacation email",
"work email", etc i am not sure how to show that in the Data model if
a message resides in that folder.
Standars folders could be like like you said ... , sent = id 3, spam = id 4, trash = id 5.
After that, any custom folder will have: vacation mail = id 6, etc...
No need for any change in the Data model.
3) One email goes to multiple people. Does this mean i need to have 1
row per user sent to?
One email, many recipients. So, yes, if you have a table for email-recipients relationship.
4) Lastly, messages have attachments. i assume that means a separate
attachments table which FK links to which ever table (s) are used for
storing messages?
Yes, like answer 3. (one email, many attachments).
If however, an attachment can be in many emails (like if one forwards an email and the attachment), and you want that in your model, the relationship will be many-to-many.
How can you create models (and thus tables) with a compound (composite) primary/unique key using Django?
Django does not support compound primary keys. You can create a single compound unique key with Meta.unique_together.
if you want only unique mixed fields together use belowcode:
class MyTable(models.Model):
class Meta:
unique_together = (('key1', 'key2'),)
key1 = models.IntegerField()
key2 = models.IntegerField()
But if you want unique together and one of column be primary, set primary argument for model column, similar below code:
class MyTable(models.Model):
class Meta:
unique_together = (('key1', 'key2'),)
key1 = models.IntegerField(primary_key=True)
key2 = models.IntegerField()