8

I have inheritance between Employee and Manager classes. Employee - superclass, Manager - subclass.

class Employee(models.Model):
    name = models.CharField(max_length=50, null=False)
    address = models.CharField(max_length=50, null=False)
    
class Manager(Employee):
    department = models.CharField(max_length=50)
    """
    Here I don't want the 'name' and 'address' fields of Employee class.
    (I want other fields of Employee and 'department' field of this 
    class to be stored in Manager table in database)
    """

How can achieve this. Thanks in advance.

6
  • Even if this was possible, that would leave the Manager without a name. Are you sure you want that? Commented Mar 17, 2017 at 14:44
  • In other languages you would make the fields of Employee private as opposed to public or protected. Commented Mar 17, 2017 at 14:44
  • Why you don't use foreingkey? Commented Mar 17, 2017 at 14:45
  • Yes I definitely want these fields to be completely removed from Manager Commented Mar 17, 2017 at 14:50
  • Put the fields you do want in an abstract model, and let both Employee and Manager inherit from that? But really, I feel inheritance shouldn't be used at all here. Commented Mar 17, 2017 at 15:14

3 Answers 3

16

You can make private variables in python class using 2 underscores (__), check this example for more.

However they will store that values in child object as there is no such thing as private or protected in Python.

But another approach can work for Django. In Django model fields are stored depending on their value (CharField, DateField and etc.) but if you will make item value None or any other static value (ex. "string"), that should solve your problem:

class Manager(Employee):
  name = None
  address = None
  # other_stuffs.

In that example, Manager should not have name and address columns in database and when you will try to access them, you will get None. And if you want to get AttributeError (Django raises that when object hasn't requested key) then you can also add property:

class Manager(Employee):
  name = None
  @property
  def name(self):
    raise AttributeError("'Manager' object has no attribute 'name'")
Sign up to request clarification or add additional context in comments.

Comments

10

I'd use 3 classes:

class BaseEmployee(models.Model):
    # All your common fields

class Employee(BaseEmployee):
    name = models.CharField(max_length=50, null=False)
    address = models.CharField(max_length=50, null=False)

class Manager(BaseEmployee):
    department = models.CharField(max_length=50)

I think that achieves what you wanted.

1 Comment

the accepted answer is not working in my case on Django 3.2 and this is a much OOP way to achieve this thank u!
1

You need to use 3 classes AbstractEmployee with abstract = True, Employee and Manager as shown below. abstract = True makes AbstractEmployee class an abstract class so a table is not created from AbstractEmployee class while each table is created from Employee and Manager classes and to remove the inherited fields name and address from Manager class, set None to them:

class AbstractEmployee(models.Model):
    name = models.CharField(max_length=50, null=False)
    address = models.CharField(max_length=50, null=False)

    class Meta:
        abstract = True # Here
    
class Employee(AbstractEmployee):
    pass
        
class Manager(AbstractEmployee):
    name = None # Here
    address = None # Here
    department = models.CharField(max_length=50)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.