Django лучшие практики для создания частных групп пользователей - PullRequest
0 голосов
/ 01 октября 2019

Я создаю групповое приложение и хочу, чтобы оно было только приглашением, но мне интересно, есть ли лучший способ сделать это. Эта установка работает нормально, но если кто-то обнаружит какие-либо проблемы, с которыми я могу столкнуться, пожалуйста, дайте мне знать. Я включил модели и представления, связанные с приглашениями, это должно дать вам хорошее представление о моем мыслительном процессе здесь.

models.py

Account = get_user_model()


class FriendGroup(models.Model):
    owner = models.ForeignKey(
        Account, on_delete=models.SET_NULL, related_name="group_owner", null=True)
    name = models.CharField(max_length=50)
    description = models.TextField(blank=True, null=True)
    administrators = models.ManyToManyField(
        Account, related_name="group_admin")
    members = models.ManyToManyField(Account, related_name="group_member")
    thumbnail = models.ImageField(upload_to='images/groups/', blank=True)
    image_lg = models.ImageField(upload_to='images/groups/', blank=True)
    date_created = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.name


class GroupInvite(models.Model):
    group = models.ForeignKey(
        FriendGroup, on_delete=models.CASCADE, related_name="invite")
    sender = models.ForeignKey(
        Account, on_delete=models.CASCADE, related_name="sent_by")
    invitee = models.ForeignKey(
        Account, on_delete=models.CASCADE, related_name="invitee")

    def __str__(self):
        return "Join " + self.group.name

views.py

class SendGroupInvitesView(APIView):

    def post(self, request, pk, format=None):
        group = FriendGroup.objects.filter(id=pk)
        invitees = request.data.get('invitees')
        if group.exists():
            if request.user in group[0].members.all():
                if invitees:
                    for invitee in invitees:
                        account = Account.objects.filter(id=invitee)
                        if account.exists():
                            invite = GroupInvite.objects.create(
                                group=group[0], sender=request.user, invitee=account[0])
                            invite.save()
                    return Response({'success': 'Invites sent.'}, status=status.HTTP_201_CREATED)
                return Response({'error': 'You must invite at least one friend.'}, status=status.HTTP_400_BAD_REQUEST)
        return Response({'error': 'Group does not exist.'}, status=status.HTTP_400_BAD_REQUEST)


class AcceptGroupInviteView(APIView):

    def post(self, request, pk, format=None):
        invite = GroupInvite.objects.filter(id=pk, invitee=request.user)
        if invite.exists():
            invite = invite[0]
            group = invite.group
            group.members.add(request.user)
            group.save()
            invite.delete()
            return Response({'success': 'Joined group.'}, status=status.HTTP_201_CREATED)
        return Response({'error': 'Invite does not exist.'}, status=status.HTTP_400_BAD_REQUEST)


class DeleteGroupInviteView(APIView):

    def post(self, request, pk, format=None):
        invite = GroupInvite.objects.filter(id=pk)
        if invite.exists():
            if invite[0].invitee == request.user or request.user in invite[0].group.members.all():
                invite = invite[0]
                invite.delete()
                return Response(status=status.HTTP_204_NO_CONTENT)
            return Response({'error': 'You are not authorized to delete this invite.'}, status=status.HTTP_401_UNAUTHORIZED)
        return Response({'error': 'Invite does not exist.'}, status=status.HTTP_400_BAD_REQUEST)

Я знаю, что мой код может показаться немного неаккуратным, может заставить менеджера немного привести себя в порядок.

1 Ответ

0 голосов
/ 02 октября 2019

Я не знаю всех ваших требований в этом задании. Но, по моему скромному мнению, вы не должны использовать два поля m2m для этого. Отношения М2М работают не быстро, поэтому было бы лучше уменьшить их количество. Взгляните на промежуточные модели. Это позволяет получить права администратора для участников через дополнительное поле.

class GroupMembers(models.Model):
    group = models.ForeignKey(FriendGroup...)
    member = models.ForeignKey(Account...)
    is_admin = models.BooleanField(default=False)


class FriendGroup(models.Model):
    ...
    members = models.ManyToManyField(Account, through=GroupMembers)
    ...

См. Документы в https://docs.djangoproject.com/en/2.2/topics/db/models/#extra-fields-on-many-to-many-relationships

...