0

我一直在努力理解如何在自定义用户和一些随机字段之间的 django rest 框架中更新 M2M 字段。我应该提到我正在使用 Djoser 作为身份验证。

假设我有一个自定义用户

楷模:

class CustomUser(AbstractUser):
    username = None
    email = models.EmailField(_('email address'), unique=True)
    paying_user = models.BooleanField(default=False)
    subscribed_companies = models.ManyToManyField('myapp.Company')

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = []

    objects = UserAccountManager()

    def __str__(self):
        return f"{self.email}' account"

class Company(models.Model):
    name = models.CharField(max_length=150)

    def __str__(self):
        return self.name
    
    class Meta:
        ordering = ['name']

我的序列化器

Imports - serializers.py:
    
        from django.contrib.auth import get_user_model
        from djoser.serializers import UserCreateSerializer
        from rest_framework import serializers
        from apartments.models.company_model import Company
    
        User = get_user_model()

class UserCreateSerializer(UserCreateSerializer):
    class Meta(UserCreateSerializer.Meta):
        model = User
        fields = ('email','password', 'paying_user', 'subscribed_companies')


class UserCompanyListSerializer(serializers.ModelSerializer):
    #Is this a reasonable way to serialize a M2M-field?
    subscribed_company_ids = serializers.PrimaryKeyRelatedField(many=True, read_only=False, 
    queryset=Company.objects.all(), source='subscribed_companies')

    class Meta:
        model = User
        fields = [
            'subscribed_company_ids'
        ]

class CompanySerializer(serializers.ModelSerializer):
    class Meta:
        model = Company
        fields = ('name',)

如您所见,我在自定义用户本身上附加了一个 M2M 字段,而不是使用存储自定义数据的 OneToOne 字段。我不确定这是最好的方法。

这个想法是,用户应该能够在前端拥有登录后想要订阅的公司列表。这意味着我将拥有许多可以订阅许多公司的用户。

我真正怀疑自己的地方是我如何处理基于班级的观点。因为我可以从 request.user.id 中检索 ID,并且我想替换整个公司列表,所以我不需要标识特定公司的 PK。因此,在put方法中,我去掉了PK参数。这行得通。

所以我的问题是 - 有没有更干净的方法呢?查看 stackoverflow 上的帖子,我找不到涉及身份验证的体面答案。我接近它错了吗?

class UserCompanies(APIView):
    permission_classes = [permissions.IsAuthenticatedOrReadOnly]
    def get(self, request):
        user_id = request.user.id
        instance = CustomUser.objects.get(id=user_id)
        serializer = UserCompanyListSerializer(instance)
        return Response(serializer.data)

    def put(self, request, format=None):
        user_id = request.user.id
        instance = CustomUser.objects.get(id=user_id)
        serializer = UserCompanyListSerializer(instance, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

GET 请求响应如何查看 localhost:8000/usercompanies/:

{
    "subscribed_company_ids": [
        2,
        1,
        3
    ]
}

PUT 请求响应在 localhost:8000/usercompanies/ 中的外观:

{
    "subscribed_company_ids": [
        2,
        1,
        3,
        5,
        4,
    ]
}

反馈将不胜感激,我是一个完全的 DRF 新手。

4

0 回答 0