0

I have a User model and a Teacher model as below User model must be created first and Teacher model is created with User as an object (ForeignKey).

User Model

class User(AbstractUser):
'''
Class to store details of Users

Attribs:
    username (str):User name.
    role_options (str): Options for role
    role (str):Whether "Admin" or "Teacher".
    email (str):User email id. 
    parent_id (obj):Self foreign key field to store creator id.
    staff (bool):If Staff
    admin (bool):If admin 
'''

username=models.CharField(
    max_length=100,default="Unknown",null=True,blank=True)
role_options = [
    ('Admin','Admin'),
    ('Teacher','Teacher'),
    ('Student','Student')
]
role = models.CharField(
    choices=role_options,max_length=40,
    null=True,blank=True)
email=models.EmailField(max_length=100,unique=True)
parent_id = models.ForeignKey(
    'self',related_name="parent_admin",
    on_delete=SET_NULL,null=True,blank=True)
staff = models.BooleanField(default=False,null=True)
admin = models.BooleanField(default=False,null=True)
USERNAME_FIELD='email'
REQUIRED_FIELDS=[]
objects=UserManager()

def get_username(self):
    return self.email

@property
def is_staff(self):
    return self.staff

@property
def is_admin(self):
    return self.admin

Teacher Model

class Teacher(models.Model):
"""
Class to store Teacher details.

Attribs:
    fullname (str): Fullname of Teacher.
    email (Obj): Email Id of Teacher
    address (str): Address of Teacher
    joining_date (str): School joining date
    qualification (str): Qualification of Teacher
"""

fullname=models.CharField(max_length=100,null=True,blank=True)
email=models.OneToOneField(
    User,related_name="Teacher",on_delete=CASCADE,null=True,blank=True)
address = models.CharField(
    max_length=200,default="Unknown",null=True,blank=True)
joining_date = models.DateField(
    null=True,default=timezone.now,blank=True)
qualification = models.CharField(max_length=40,null=True,blank=True)

I have created a serializer for creating User as given below

class UserSerializer(serializers.ModelSerializer):
"""Serializer for creating user."""
class Meta:
    model = User
    fields = [
        'id',
        'email',
        'password',
        'role'
    ]

I want to create a User and use it's instance to create a Teacher, simultaneously from the same serializer. How can i do that?

My api view is given below

class TeacherCreate(CreateAPIView):
""" View for Creating Teacher """

authentication_classes = [TokenAuthentication]
permission_classes = [IsAuthenticated,AdminOnly]
serializer_class = TeacherCreateSerilaizer

1 Answers1

0

First of all your model design is not good. Let me start from there.

Please refer Django Auth Model and the model fields and properties, You don't need to specify any of these admin (there you have is_admin), email, staff( there you have is_staff), username fields

Models:

class User(AbstractUser):
    ADMIN = 'Admin'
    TEACHER = 'Teacher'
    STUDENT = 'Student'
    role_options = (
        (ADMIN, 'Admin'),
        (TEACHER, 'Teacher'),
        (STUDENT, 'Student')
    )
    role = models.CharField(choices=role_options, max_length=40, default=TEACHER)
    REQUIRED_FIELDS = ['first_name']
    USERNAME_FIELD = 'email'
    

class Teacher(models.Model):
    qualification = models.CharField(max_length=120)
    user = models.OneToOneField(User, related_name='staff_info', on_delete=models.CASCADE)
    joining_date = models.DateField(null=True, default=timezone.now, blank=True)

Serializers:

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ('id', 'email', 'first_name', 'last_name', 'role', 'is_admin', 'is_staff') 


class TeacherSerializer(serializers.ModelSerializer):
    user = UserSerializer()
    class Meta:
        model = Teacher
        fields = ('id', 'qualification', 'user', 'joining_date')

Views:

class TeacherAPIView(ModelViewSet):
     serializer_class = TeacherSerializer
     lookup_field = "id"
     permission_classes = (IsAuthenticated, )

     def get_queryset(self):
         return User.objects.filter(is_active=True)

 
  • You can do create, update, list, delete and retrieve actions using this. Also you can write your custom requests by overriding the create(), update(), retrieve(), list() and destroy() methods –  Jan 23 '22 at 12:22
  • Thanks for your suggestions, The get request is working but while creating teacher, user account is not created and user field stays null. Kindly answer this question - Is there any way by which user is created first and its instance is used to create teacher without overriding the create function? (Using a nested serializer) – Christo Johnson Jan 25 '22 at 11:23
  • @ChristoJohnson Please comment your request json. Then only I can provide you the answer –  Jan 25 '22 at 13:05