Django, назначьте отношение «многие ко многим» между двумя таблицами с предопределенными значениями в обеих таблицах - PullRequest
0 голосов
/ 22 февраля 2019

В настоящее время я использую django rest framework.Я хочу повторить выбор роли по умолчанию для django в форме остальных API.Я перечислил auth_group с разрешением внутри него.Проблема: разрешение и группа уже выбраны в базе данных.Я только хочу создать связь между группой и разрешением, используя таблицы по умолчанию в django.(Я хочу назначить разрешение для группы.)

Вот мои сериализаторы.

class PermissionSerializer(serializers. HyperlinkedModelSerializer): 
    class Meta:        
        model = Permission        
        fields = (
            'pk', 
            'codename',
            'name'
        )      
        read_only_fields = ('pk',)

class UserGroupSerializer(serializers. HyperlinkedModelSerializer): 
    permissions = PermissionSerializer(many=True, read_only=True)
    class Meta:        
        model = Group        
        fields = (
            'pk', 
            'name',
            'permissions'
        )      
        read_only_fields = ('pk',)

    def create(self, validated_data):
        """
        Overriding the default create method of the Model serializer.
        """
        permission_data = validated_data.pop('permissions')
        group = Group.objects.create(**validated_data)
        for permission in permission_data:
            permissionNow = Permission.objects.get(name='view_profile')
            group.permissions.add(permissionNow)
        return group

views.py

def index(request):
    # retrive all users or create a user
    if request.method == 'GET':
        groups = Group.objects.all()
        serializer = UserGroupSerializer(groups, many=True)
        return Response(serializer.data)

def create(request):
    if request.method == 'POST':
        serializer = UserGroupSerializer(data = request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

в настоящее время это дает

Exception Type: KeyError
Exception Value:    
'permissions'. 

И я не хочу создавать разрешение, потому что оно уже доступно в БД.Единственное, что я хочу, это сохранить связь между группой и разрешением.(назначить существующие разрешения для существующих групп).Спасибо

1 Ответ

0 голосов
/ 22 февраля 2019

измените следующее

 permissions = PermissionSerializer(many=True)

на

 permissions = PermissionSerializer(read_only=True, many=True)

update

В цикле django-restframework-serializer последовательно выполняются определенные действия.Что касается вашего случая, я предположил, как пройти проверку валидации поля разрешений.всякий раз, когда вы объявляете другой сериализатор, который в PermissionSerializer в этом поле, которое ожидает следующего, должен пройти проверку этого сериализатора, где требуются codename и name, и, конечно, не передавая их, вот почему вы получаете эту ошибку.Если мы присвоим это поле как read_only, следующая проверка будет проходить в обход.Я надеюсь, что вы получите разрешения для validated_data, если его там нет, вы можете получить от self.context['request']data.get('permissions') в вашем переписанном методе create.

Edit

UserGroupSerializer должен выглядеть следующим образом

class UserGroupSerializer(serializers. HyperlinkedModelSerializer): 
    permissions = PermissionSerializer(many=True, read_only=True)
    class Meta:        
        model = Group        
        fields = (
            'pk', 
            'name',
            'permissions'
        )      
        read_only_fields = ('pk',)

    def create(self, validated_data):
        """
        Overriding the default create method of the Model serializer.
        """
        permission_data = self.context['request'].data.get('permissions')
        group = Group.objects.create(**validated_data)
        for permission in permission_data:
            permissionNow = Permission.objects.get(name='view_profile')
            group.permissions.add(permissionNow)
        return group

А также в представлениях

def create(request):
    if request.method == 'POST':
        serializer = UserGroupSerializer(data = request.data, context={'request': request})
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

Как передать контекстные данные в сериализатор, соответствующие показания ссылка

...