Re: Using composition in Django
Thanks for the clarification, I put in the ForeignKey in employee class and is working. Regards! 2011/4/27 Tom Evans> On Sun, Apr 17, 2011 at 9:21 PM, W Craig Trader > wrote: > > If your goal is to have an employee object that has direct access to all > of > > its related person object, and whose only new data field is a reference > to > > an address object, then you should change the Employee model to this: > > > > class Address(models.Model): > >pass > > > > class Person(models.Model): > >name = models.CharField(max_length=50) > >date_inclusion = models.DateField() > > > > class Employee(models.Model): > >person = models.OneToOneField(Person) > >address = models.ForeignKey(Address) > > > > Just to point out, this is MTI reinvented, without any of the Django > syntactic magic sprinkled on top. It is exactly equivalent to this: > > class Address(models.Model): >pass > > class Person(models.Model): >name = models.CharField(max_length=50) >date_inclusion = models.DateField() > > class Employee(Person): >address = models.ForeignKey(Address) > > """ > The second type of model inheritance supported by Django is when each > model in the hierarchy is a model all by itself. Each model > corresponds to its own database table and can be queried and created > individually. The inheritance relationship introduces links between > the child model and each of its parents (via an automatically-created > OneToOneField). > """ > > > http://docs.djangoproject.com/en/1.3/topics/db/models/#multi-table-inheritance > > Cheers > > Tom > > -- > You received this message because you are subscribed to the Google Groups > "Django users" group. > To post to this group, send email to django-users@googlegroups.com. > To unsubscribe from this group, send email to > django-users+unsubscr...@googlegroups.com. > For more options, visit this group at > http://groups.google.com/group/django-users?hl=en. > > -- You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-users@googlegroups.com. To unsubscribe from this group, send email to django-users+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/django-users?hl=en.
Re: Using composition in Django
On Sun, Apr 17, 2011 at 9:21 PM, W Craig Traderwrote: > If your goal is to have an employee object that has direct access to all of > its related person object, and whose only new data field is a reference to > an address object, then you should change the Employee model to this: > > class Address(models.Model): > pass > > class Person(models.Model): > name = models.CharField(max_length=50) > date_inclusion = models.DateField() > > class Employee(models.Model): > person = models.OneToOneField(Person) > address = models.ForeignKey(Address) > Just to point out, this is MTI reinvented, without any of the Django syntactic magic sprinkled on top. It is exactly equivalent to this: class Address(models.Model): pass class Person(models.Model): name = models.CharField(max_length=50) date_inclusion = models.DateField() class Employee(Person): address = models.ForeignKey(Address) """ The second type of model inheritance supported by Django is when each model in the hierarchy is a model all by itself. Each model corresponds to its own database table and can be queried and created individually. The inheritance relationship introduces links between the child model and each of its parents (via an automatically-created OneToOneField). """ http://docs.djangoproject.com/en/1.3/topics/db/models/#multi-table-inheritance Cheers Tom -- You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-users@googlegroups.com. To unsubscribe from this group, send email to django-users+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/django-users?hl=en.
Re: Using composition in Django
Hello Craig! Thanks for the reply! Actually I want to use a form that will save the Employee data and would be sent to the Employee class, and this class has relationship with the Person and Address, the data would automatically be persisted. Follow the instructions you suggested and they match what the manual says: http://docs.djangoproject.com/en/dev/topics/db/models/#relationships I did classes like this: class Employee (models.Model): person = models.OneToOneField(Person) # only one person related address = models.OneToOneField(Address) # only one address for employee sectors= models.ForeignKey(Sectors) # one or various sectors for the employee This is the SQL: CREATE TABLE "employee_employee" ( "id" serial NOT NULL PRIMARY KEY, "person_id" integer NOT NULL UNIQUE, "address_id" integer NOT NULL UNIQUE, "sectors_id" integer NOT NULL ) Thanks for help! On 17 abr, 17:21, W Craig Traderwrote: > On 04/16/2011 04:35 PM, Guevara wrote: > > > > > > > > > > > Hello! > > I have two class, Person and employee, i need make a composition for > > this (Prefer composition over inheritance): > > > class Person(models.Model): > > name = models.CharField(max_length=50) > > date_inclusion = models.DateField() > > # others fields > > > class Employee(models.Model): > > person = models.OneToOneField(Person, primary_key=True) > > address = models.OneToOneField(Address, primary_key=True) > > > The SQL generate is: > > > BEGIN; > > CREATE TABLE "person_person" ( > > "id" serial NOT NULL PRIMARY KEY, > > "name" varchar(50) NOT NULL, > > "date_inclusion" date NOT NULL, > > ) > > ; > > CREATE TABLE "employee_employee" ( > > "person_id" integer NOT NULL PRIMARY KEY, > > "address_id" integer NOT NULL PRIMARY KEY, > > ) > > ; > > > This is correct? Should generate the id of the employee? > > Proxy models could be used for this case? > > > Thanks! > > It's correct in that Django has done exactly what you've told it you want, > but I doubt that what > you've told it is what you REALLY want. > > If your goal is to have an employee object that has direct access to all of > its related person > object, and whose only new data field is a reference to an address object, > then you should change > the Employee model to this: > > class Address(models.Model): > pass > > class Person(models.Model): > name = models.CharField(max_length=50) > date_inclusion = models.DateField() > > class Employee(models.Model): > person = models.OneToOneField(Person) > address = models.ForeignKey(Address) > > This will change the generated employee table to something like this (for > SQLite3): > > CREATE TABLE "foo_address" ( > "id" integer NOT NULL PRIMARY KEY > ) > ; > CREATE TABLE "foo_person" ( > "id" integer NOT NULL PRIMARY KEY, > "name" varchar(50) NOT NULL, > "date_inclusion" date NOT NULL > ) > ; > CREATE TABLE "foo_employee" ( > "id" integer NOT NULL PRIMARY KEY, > "person_id" integer NOT NULL UNIQUE REFERENCES "foo_person" ("id"), > "address_id" integer NOT NULL REFERENCES "foo_address" ("id") > ) > ; > CREATE INDEX "foo_employee_b213c1e9" ON "foo_employee" ("address_id"); > > With these models, every Employee object will have an equivalent Person > object (though you may have Persons without corresponding Employees). You > can then use these models as follows: > > (InteractiveConsole)>>> from foo.models import * > >>> from datetime import datetime > >>> now = datetime.now() > >>> p = Person( name='Tom', date_inclusion=now ) > >>> p.save() > >>> a = Address() > >>> a.save() > >>> e = Employee( person=p, address=a ) > >>> e.save() > >>> e.person.name > > 'Tom' > > - Craig - -- You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-users@googlegroups.com. To unsubscribe from this group, send email to django-users+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/django-users?hl=en.
Re: Using composition in Django
On 04/16/2011 04:35 PM, Guevara wrote: Hello! I have two class, Person and employee, i need make a composition for this (Prefer composition over inheritance): class Person(models.Model): name = models.CharField(max_length=50) date_inclusion = models.DateField() # others fields class Employee(models.Model): person = models.OneToOneField(Person, primary_key=True) address = models.OneToOneField(Address, primary_key=True) The SQL generate is: BEGIN; CREATE TABLE "person_person" ( "id" serial NOT NULL PRIMARY KEY, "name" varchar(50) NOT NULL, "date_inclusion" date NOT NULL, ) ; CREATE TABLE "employee_employee" ( "person_id" integer NOT NULL PRIMARY KEY, "address_id" integer NOT NULL PRIMARY KEY, ) ; This is correct? Should generate the id of the employee? Proxy models could be used for this case? Thanks! It's correct in that Django has done exactly what you've told it you want, but I doubt that what you've told it is what you REALLY want. If your goal is to have an employee object that has direct access to all of its related person object, and whose only new data field is a reference to an address object, then you should change the Employee model to this: class Address(models.Model): pass class Person(models.Model): name = models.CharField(max_length=50) date_inclusion = models.DateField() class Employee(models.Model): person = models.OneToOneField(Person) address = models.ForeignKey(Address) This will change the generated employee table to something like this (for SQLite3): CREATE TABLE "foo_address" ( "id" integer NOT NULL PRIMARY KEY ) ; CREATE TABLE "foo_person" ( "id" integer NOT NULL PRIMARY KEY, "name" varchar(50) NOT NULL, "date_inclusion" date NOT NULL ) ; CREATE TABLE "foo_employee" ( "id" integer NOT NULL PRIMARY KEY, "person_id" integer NOT NULL UNIQUE REFERENCES "foo_person" ("id"), "address_id" integer NOT NULL REFERENCES "foo_address" ("id") ) ; CREATE INDEX "foo_employee_b213c1e9" ON "foo_employee" ("address_id"); With these models, every Employee object will have an equivalent Person object (though you may have Persons without corresponding Employees). You can then use these models as follows: (InteractiveConsole) from foo.models import * from datetime import datetime now = datetime.now() p = Person( name='Tom', date_inclusion=now ) p.save() a = Address() a.save() e = Employee( person=p, address=a ) e.save() e.person.name 'Tom' - Craig - -- You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-users@googlegroups.com. To unsubscribe from this group, send email to django-users+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/django-users?hl=en.
Re: Using composition in Django
Thanks for the replies! if I leave the class person like this: class Employee(models.Model): person = models.OneToOneField(Person) This is SQL generated: CREATE TABLE "person_person" ( "id" serial NOT NULL PRIMARY KEY, "name" varchar(50) NOT NULL, ) ; CREATE TABLE "employee_employee" ( "person_id" integer NOT NULL UNIQUE, "address_id" integer NOT NULL PRIMARY KEY, ) And when I need to get the employee data, I call Person or Employee? I can call the Employee who is using the person_id? Thanks!! On 16 abr, 20:06, Ian Clellandwrote: > On Sat, Apr 16, 2011 at 1:35 PM, Guevara wrote: > > Hello! > > I have two class, Person and employee, i need make a composition for > > this (Prefer composition over inheritance): > > > class Person(models.Model): > > name = models.CharField(max_length=50) > > date_inclusion = models.DateField() > > # others fields > > > class Employee(models.Model): > > person = models.OneToOneField(Person, primary_key=True) > > address = models.OneToOneField(Address, primary_key=True) > > > The SQL generate is: > > > BEGIN; > > CREATE TABLE "person_person" ( > > "id" serial NOT NULL PRIMARY KEY, > > "name" varchar(50) NOT NULL, > > "date_inclusion" date NOT NULL, > > ) > > ; > > CREATE TABLE "employee_employee" ( > > "person_id" integer NOT NULL PRIMARY KEY, > > "address_id" integer NOT NULL PRIMARY KEY, > > ) > > ; > > > This is correct? Should generate the id of the employee? > > I don't think it's correct -- a database table shouldn't have two distinct > primary keys. It's the "primary_key=True" part of your Employee model fields > that is doing this, and is also stopping an "id" field from being > automatically generated. > > If you write Employee like this: > > class Employee(models.Model): > person = models.OneToOneField(Person) > address = models.OneToOneField(Address) > > Then it will generate SQL like this: > > CREATE TABLE "employee_employee" ( > "id" serial NOT NULL PRIMARY KEY, > "person_id" integer NOT NULL, > "address_id" integer NOT NULL > ) > ; > > which is probably closer to what you're expecting. > > -- > Regards, > Ian Clelland > -- You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-users@googlegroups.com. To unsubscribe from this group, send email to django-users+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/django-users?hl=en.
Re: Using composition in Django
On Sat, Apr 16, 2011 at 1:35 PM, Guevarawrote: > Hello! > I have two class, Person and employee, i need make a composition for > this (Prefer composition over inheritance): > > class Person(models.Model): >name = models.CharField(max_length=50) >date_inclusion = models.DateField() ># others fields > > class Employee(models.Model): >person = models.OneToOneField(Person, primary_key=True) >address = models.OneToOneField(Address, primary_key=True) > > > The SQL generate is: > > > BEGIN; > CREATE TABLE "person_person" ( >"id" serial NOT NULL PRIMARY KEY, >"name" varchar(50) NOT NULL, >"date_inclusion" date NOT NULL, > ) > ; > CREATE TABLE "employee_employee" ( >"person_id" integer NOT NULL PRIMARY KEY, >"address_id" integer NOT NULL PRIMARY KEY, > ) > ; > > > This is correct? Should generate the id of the employee? > I don't think it's correct -- a database table shouldn't have two distinct primary keys. It's the "primary_key=True" part of your Employee model fields that is doing this, and is also stopping an "id" field from being automatically generated. If you write Employee like this: class Employee(models.Model): person = models.OneToOneField(Person) address = models.OneToOneField(Address) Then it will generate SQL like this: CREATE TABLE "employee_employee" ( "id" serial NOT NULL PRIMARY KEY, "person_id" integer NOT NULL, "address_id" integer NOT NULL ) ; which is probably closer to what you're expecting. -- Regards, Ian Clelland -- You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-users@googlegroups.com. To unsubscribe from this group, send email to django-users+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/django-users?hl=en.
Re: Using composition in Django
Hi Guevara, Proxy models only inherit python logic, they are what you expect when you subclass a superclass; I dont think thats what you want in this case. I think you actually do want multi-table inheritence, im not too well educated in "design patterns" but i think thats what you mean by composition. However, allthough Python itselfs supports multiple-inheretence, im not sure if that works with more then two Django models. Subclassing a Django model implies a OneToOne relationship which is automaticly generated. An instance of employee should then contain fields from both Person and Adress on the python layer, and contain only the foreign keys on the database layer. Again i'm not sure if this works with 3 models involved (Address, Person and Employee). Take a look at http://docs.djangoproject.com/en/1.3/topics/db/models/#multi-table-inheritance This is what i mean: class Person(models.Model): first_name ... last_name ... class Adress(models.Model): street ... city ... class Employee(Person, Adress): pass Regards, Yuka On Sat, Apr 16, 2011 at 10:35 PM, Guevarawrote: > Hello! > I have two class, Person and employee, i need make a composition for > this (Prefer composition over inheritance): > > class Person(models.Model): > name = models.CharField(max_length=50) > date_inclusion = models.DateField() > # others fields > > class Employee(models.Model): > person = models.OneToOneField(Person, primary_key=True) > address = models.OneToOneField(Address, primary_key=True) > > > The SQL generate is: > > > BEGIN; > CREATE TABLE "person_person" ( > "id" serial NOT NULL PRIMARY KEY, > "name" varchar(50) NOT NULL, > "date_inclusion" date NOT NULL, > ) > ; > CREATE TABLE "employee_employee" ( > "person_id" integer NOT NULL PRIMARY KEY, > "address_id" integer NOT NULL PRIMARY KEY, > ) > ; > > > This is correct? Should generate the id of the employee? > Proxy models could be used for this case? > > Thanks! > > -- > You received this message because you are subscribed to the Google Groups > "Django users" group. > To post to this group, send email to django-users@googlegroups.com. > To unsubscribe from this group, send email to > django-users+unsubscr...@googlegroups.com. > For more options, visit this group at > http://groups.google.com/group/django-users?hl=en. > > -- You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-users@googlegroups.com. To unsubscribe from this group, send email to django-users+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/django-users?hl=en.
Using composition in Django
Hello! I have two class, Person and employee, i need make a composition for this (Prefer composition over inheritance): class Person(models.Model): name = models.CharField(max_length=50) date_inclusion = models.DateField() # others fields class Employee(models.Model): person = models.OneToOneField(Person, primary_key=True) address = models.OneToOneField(Address, primary_key=True) The SQL generate is: BEGIN; CREATE TABLE "person_person" ( "id" serial NOT NULL PRIMARY KEY, "name" varchar(50) NOT NULL, "date_inclusion" date NOT NULL, ) ; CREATE TABLE "employee_employee" ( "person_id" integer NOT NULL PRIMARY KEY, "address_id" integer NOT NULL PRIMARY KEY, ) ; This is correct? Should generate the id of the employee? Proxy models could be used for this case? Thanks! -- You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-users@googlegroups.com. To unsubscribe from this group, send email to django-users+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/django-users?hl=en.