So in my project, I have a User model and a School model. My user model has a schools
field that has an M2M relation with the School model. Now what I want to know is, how can I create a view that can take the email of a user and the school Id, and add the school or delete it from the schools that a user
belongs to.
Here is my user model
:
class User(AbstractBaseUser, PermissionsMixin):
username = models.CharField(max_length=255, unique=True, db_index=True)
email = models.EmailField(max_length=255, unique=True, db_index=True)
is_verified = models.BooleanField(default=False)
is_active = models.BooleanField(default=False)
is_staff = models.BooleanField(default=False)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now_add=True)
schools = models.ManyToManyField("School", related_name="members")
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['username']
objects = UserManager()
def __str__(self):
return self.email
def tokens(self):
refresh = RefreshToken.for_user(self)
return {
'refresh': str(refresh),
'access': str(refresh.access_token)
}
School:
class School(models.Model):
name = models.CharField(max_length=300, verbose_name='school name', )
principal = models.ForeignKey("User", related_name="my_schools", on_delete=CASCADE)
address = models.CharField(max_length=200)
class Type(models.IntegerChoices):
PUBLIC = 1, "Public"
PRIVATE = 2, "Private"
type = models.PositiveSmallIntegerField(choices=Type.choices, default=Type.PUBLIC)
class Level(models.IntegerChoices):
NATIONAL = 1, "National"
EXTRACOUNTY = 2, "Extra County"
COUNTY = 3, "County"
SUBCOUNTY = 4, "Subcounty"
level = models.PositiveSmallIntegerField(choices=Level.choices, default=Level.COUNTY)
def __str__(self):
return self.name
Here is the serializer to enroll the members:
class EnrollSchoolMembersSerializer():
class Meta:
model = User
field = ('email')
CodePudding user response:
I think you can implement that using function API view. First, you can define the serializer.
from rest_framework import serializers as sz
class SchoolUpdateSerializer(sz.Serializer):
school_id = sz.IntegerField()
email = sz.EmailField()
mode = sz.CharField() # can be either 'add' or 'delete'
And in views.py, you can write the handler.
from rest_framework.response import Response
from rest_framework status
from rest_framework.decorators import api_view, permission_classes
from .models import School, User
from .serializers import SchoolUpdateSerializer
@api_view(['POST'])
@permission_classes([permissions.AllowAny])
def update_school_data(request):
serializer = SchoolUpdateSerializer(data = request.data)
if serializer.is_valid()
input_data = serializer.validated_data
email = input_data.get('email')
mode = input_data.get('mode')
school_id = input_data.get('school_id')
try:
user = User.objects.get(email = email)
school = School.objects.get(pk = school_id)
if mode == "add":
user.schools.add(school)
else:
user.schools.remove(school)
return Response(status = status.HTTP_200_OK)
except (User.DoesNotExist, School.DoesNotExist):
return Response(status = status.HTTP_400_BAD_REQUEST)
else:
return Response(status = status.HTTP_400_BAD_REQUEST)
And finally in frontend, you can use POST API. The payload can be
{
"email": "[email protected]",
"school_id": 1,
"mode": "add"
}
CodePudding user response:
See the documentation of Django REST framework at https://www.django-rest-framework.org/api-guide/serializers/#writing-update-methods-for-nested-representations