Как расшифровать зашифрованное <path:pk> и передать его функции generics.RetrieveUpdateDestroyAPIView - Django

Я хочу передать зашифрованные идентификаторы объектов в Response, поэтому я использовал AES. Теперь я хочу принять зашифрованный pk, который является путем 'xx/xx/xxx/xxx', и расшифровать его первым делом в представлении.

`

import base64, re
from Crypto.Cipher import AES
from Crypto import Random
from django.conf import settings

import codecs

# make utf8mb4 recognizable.
codecs.register(lambda name: codecs.lookup('utf8') if name == 'utf8mb4' else None)


class AESCipher:

    def __init__(self, key, blk_sz):
        self.key = key
        self.blk_sz = blk_sz

    def encrypt( self, raw ):
        # raw is the main value
        if raw is None or len(raw) == 0:
            raise NameError("No value given to encrypt")
        raw = raw + '\0' * (self.blk_sz - len(raw) % self.blk_sz)
        raw = raw.encode('utf8mb4')
        # Initialization vector to avoid same encrypt for same strings.
        iv = Random.new().read( AES.block_size )
        cipher = AES.new( self.key.encode('utf8mb4'), AES.MODE_CFB, iv )
        return base64.b64encode( iv + cipher.encrypt( raw ) ).decode('utf8mb4')

    def decrypt( self, enc ):
        # enc is the encrypted value
        if enc is None or len(enc) == 0:
            raise NameError("No value given to decrypt")
        enc = base64.b64decode(enc)
        iv = enc[:16]
        # AES.MODE_CFB that allows bigger length or latin values
        cipher = AES.new(self.key.encode('utf8mb4'), AES.MODE_CFB, iv )
        return re.sub(b'\x00*$', b'', cipher.decrypt( enc[16:])).decode('utf8mb4')

`

Я пытался принять path:pk в url и расшифровать этот pk в get_queryset(), но ответ любой функции - объект не найден `

path('<path:pk>/detail/',ProductDetailUpdateDelete.as_view(),name='product-detail'),

and override the get_queryset


class ProductDetailUpdateDelete(generics.RetrieveUpdateDestroyAPIView):

serializer_class=ProductSerializer
   
def get_queryset(self):
    pk = aes.decrypt(str(self.kwargs['pk']))
    product=Product.objects.filter(pk=int(pk))
    return product

`

это возвращает объект, и я могу получить доступ ко всей информации, но все операции (GET, PUT, DEL) возвращают ошибку. как я могу передать идентификатор объекта функциям, и мне нужен способ расшифровать pk до вызова любой функции, чтобы передать pk без переопределения каждой функции

Попробуйте переопределить базовую функцию get_object.

def get_object(self):
    pk = aes.decrypt(str(self.kwargs['pk']))
    product=Product.objects.filter(pk=int(pk))
    return product

ответом является переопределение метода get_object, но проблема с

def get_object(self):
    pk = aes.decrypt(str(self.kwargs['pk']))
    product=Product.objects.filter(pk=int(pk))
    return product

это возвращает правильный объект, но с типом: <class 'django.db.models.query.QuerySet'>, а чтобы иметь доступ к атрибутам объекта, нам нужно, чтобы возвращаемый объект был типа: <class 'products_app.models.Product'>. Но возвращаемый QuerySet содержит только один объект, который и является искомым объектом, поэтому я использовал это для решения своей проблемы

def get_object(self):
    pk = aes.decrypt(str(self.kwargs['pk']))
    product=Product.objects.filter(pk=int(pk))
    return product[0]
Вернуться на верх