I am building an API with DRF. I have two models, Folder and User, connected through a ManyToMany field.
models.py
class Folder(models.Model):
title = models.CharField(max_length=20)
description = models.CharField(max_length=250)
organization = models.ForeignKey(Organization, on_delete=models.CASCADE)
users = models.ManyToManyField(User, related_name='folders')
def __str__(self):
return self.title
class User(AbstractBaseUser, PermissionsMixin):
username = None
email = models.EmailField(_('email address'), unique=True)
first_name = models.CharField(max_length=20)
last_name = models.CharField(max_length=20)
organization = models.ForeignKey(
Organization, on_delete=models.CASCADE, null=True, blank=True)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = []
objects = UserManager()
def __str__(self):
return self.email
serializers.py
class FolderSerializer(serializers.ModelSerializer):
class Meta:
model = Folder
fields = ("id", "title", "description", "users", "organization")
def create(self, validated_data):
users = validated_data.pop('users') if 'users' in validated_data else []
folder = Folder.objects.create(**validated_data)
for user in users:
if user in User.objects.all():
User.objects.filter... **not sure**
else
User.objects.create(folder=folder, **user)
return folder
The part I am stuck on is the custom create method: basically, users do not get created when the folder is created, they just get added to the newly created folder, so I think that in the for loop for user in users I should check if user exists within the instances of model User and if it does, I should update its property folder. I have no idea how to do so though.
Also, I am not sure if this is the right approach to achieve what I need: a list of users that can be added to folders. Each folder can have many users and each user can be in many folders.
By the way, I also did customize the POST request in the view but it does not work. I'll add it here just to give a complete overview of the current code.
views.py
class FolderViewSet(viewsets.ModelViewSet):
permission_classes = [permissions.IsAuthenticated, ]
serializer_class = FolderSerializer
def get_queryset(self):
a = Folder.objects.filter(
organization=self.request.user.organization)
b = a.filter(users__id=self.request.user.id)
return b.order_by('title')
def post(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
folder = serializer.save(users=[].append(self.request.user), organization=self.request.user.organization)
return Response(FolderSerializer(folder, context=self.get_serializer_context()).data)
Thanks a lot in advance for helping out, cheers.
You're almost there! For setting the users to the folder, you can use m2m set
to add all those users to the folder like this:
def create(self, validated_data):
users = validated_data.pop('users') if 'users' in validated_data else []
folder = Folder.objects.create(**validated_data)
folder.users.set(users)
return folder
I believe users
here are already instances of User
so this should work.