is it safe to refactor my django models? - django-models

My model is similar to this. Is this ok or should I make the common base class abstract? What are the differcenes between this or makeing it abstract and not having an extra table? It seems odd that there is only one primary key now that I have factored stuff out.
class Input(models.Model):
details = models.CharField(max_length=1000)
user = models.ForeignKey(User)
pub_date = models.DateTimeField('date published')
rating = models.IntegerField()
def __unicode__(self):
return self.details
class Case(Input):
title = models.CharField(max_length=200)
views = models.IntegerField()
class Argument(Input):
case = models.ForeignKey(Case)
side = models.BooleanField()
is this ok to factor stuff out intpu Input? I noticed Cases and Arguments share a primary Key.
like this:
CREATE TABLE "cases_input" (
"id" integer NOT NULL PRIMARY KEY,
"details" varchar(1000) NOT NULL,
"user_id" integer NOT NULL REFERENCES "auth_user" ("id"),
"pub_date" datetime NOT NULL,
"rating" integer NOT NULL
)
;
CREATE TABLE "cases_case" (
"input_ptr_id" integer NOT NULL PRIMARY KEY REFERENCES "cases_input" ("id"),
"title" varchar(200) NOT NULL,
"views" integer NOT NULL
)
;
CREATE TABLE "cases_argument" (
"input_ptr_id" integer NOT NULL PRIMARY KEY REFERENCES "cases_input" ("id"),
"case_id" integer NOT NULL REFERENCES "cases_case" ("input_ptr_id"),
"side" bool NOT NULL
)

From: django web site
Abstract base classes are useful when you want to put some common information into a number of other models. You write your base class and put abstract=True in the Meta class. This model will then not be used to create any database table. Instead, when it is used as a base class for other models, its fields will be added to those of the child class.

Related

Foreign key related to self. Creating an instance

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)

Django: How to have a multiple foreign keys references the same table in one table

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.

A Castle ActiveRecord relationship that does not use the Primary Key

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.

Mail / Messaging schema question

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.

Compound/Composite primary/unique key with Django

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

Resources