1

EDIT: Advantages and disadvantages of both methods. SO, I have three models: Person, Client, Member Person is a base model, Client and Member are profiles for Person.

class Person(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField(
        verbose_name=_('email address'),
        max_length=255,
        unique=True,
    )

class Client(User): #or maybe models.Model and explicit OneToField 
    first_name = models.CharField(verbose_name=_('first name'), max_length=30)
    last_name = models.CharField(verbose_name=_('last name'), max_length=30)

class Member(User): #or maybe models.Model and explicit OneToField 
    description = models.CharField(verbose_name=_('first name'), max_length=255)
   # other stuff

So, what I want?

  1. In admin, when we add client or member, I want to fill field email (fields from base class) as if it was in derived class. For example, in admin list_display = ('email', 'first_name'). Not select boxes for user.

  2. Person class can be instantiated separately and the "attached" to the created profiel. Like person=Person(email="test@gmail.com"), client = Client(person=person,first_name="test"...). Especially, this should work in forms. When user (person) is authenticated I want to give ability to fill in profile (client) form and attach person to this form.

  3. One person can have both accounts. If I delete client/member, corresponding person should not be deleted.

3rd option actually is not necessary, but it is useful for me to know how to do it.

So, option 1 is perfectly solved by inheritance, Person is User, but this approach fails when option 2 is implemented. Since Person and Client are considered as one whole, I can't attach user, duplicate key error.

Option 2 is resolved by extending models.Model and appending person=models.OnetoOneField(Person,primary_key=True). However, admin is broken (1st option), because Client don't have fields like email.

So, what approach to take in order to solve above issues? Are there simple ways? If there are no simple ways, is there advanced way, like overriding metaclass, object descriptors or writing custom OneToOne field?

Any suggestions are welcomed.

Thank you.

Paul R
  • 2,631
  • 3
  • 38
  • 72

1 Answers1

2

You can use the post_delete signal for this.

So you would:

  • Register the post_delete signals on both the models
  • One delet, check if the other object exists, and delete.

There are lots of examples on the implementation of post_delete signals on StackOverflow, so i will leave that part out.

karthikr
  • 97,368
  • 26
  • 197
  • 188
  • So, it is better to use OneToOne field? – Paul R Jan 18 '15 at 22:10
  • Yes, i do think OneToOne field serves your purpose. An alternate approach would be to have (nullable)`ForeignKeys` on the model `Person`. But I would take the `OneToOne` approach though.. – karthikr Jan 18 '15 at 22:14