Как расшифровать зашифрованное <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]