gpt4 book ai didi

python - Django Admin 使用 save_model() 加密更改(或保存)时某些字段的值

转载 作者:行者123 更新时间:2023-12-02 06:36:18 25 4
gpt4 key购买 nike

我目前有一个自定义用户模型,其中一些字段应该被加密(数据侧),但在 Django Admin 上,它们需要解密才能显示实际数据,所以我有 encrypt_string()decrypt_string() 函数来处理它。

我的用户模型:

class User(AbstractUser):
uid = models.CharField(
"uid", max_length=255, null=True, blank=True)
nickname = models.CharField(
"Nickname", max_length=255, null=True, blank=True)

eth_address = models.CharField(
"Eth address", max_length=255, null=True, blank=True)
eth_private_key = models.CharField(
"Eth private key", max_length=255, null=True, blank=True)
evt_address = models.CharField(
"Evt address", max_length=255, null=True, blank=True)
evt_private_key = models.CharField(
"Evt private key", max_length=255, null=True, blank=True)

在进行任何类型的保存或编辑时,eth_address、eth_private_key、evt_address 和 evt_private_key 需要加密

当前,当我的服务器从 api 请求时,它将创建一个默认用户(处理 django-rest-framework 的自定义authentication_class):

existed_user_check = User.objects.filter(uid=uid).exists()

    if not existed_user_check:
random_password = ''.join(["{}".format(randint(0, 9)) for num in range(0, 6)])
eth_address, eth_private_key = generate_eth()
evt_address, evt_private_key = generate_evt()
new_user = User(
username=uid,
uid=uid,
eth_address=encrypt_string(eth_address),
eth_private_key=encrypt_string(eth_private_key),
evt_address=encrypt_string(evt_address),
evt_private_key=encrypt_string(evt_private_key)
)
new_user.set_password(random_password)
new_user.save()

在我的 Django Admin 中,我在 admin.py 中编写了以下内容来处理解密(在更改 View 上显示数据时)和加密(在对这 4 个字段进行任何保存或编辑时):

user_profile_encrypt_fields = [
'eth_address',
'eth_private_key',
'evt_address',
'evt_private_key'
]
class UserAdminForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(UserAdminForm, self).__init__(*args, **kwargs)
for field in user_profile_encrypt_fields:
if getattr(self.instance, field) is not None:
try:
self.initial[field] = decrypt_string(getattr(self.instance, field))
except Exception as e:
pass


class UserAdminCustom(admin.ModelAdmin):
# UserAdminForm handle decrypt data
form = UserAdminForm
exclude = ('password', 'last_login', 'is_superuser', 'is_staff', 'groups',
'user_permissions', 'username', 'first_name', 'last_name', 'is_active', 'date_joined')

def get_queryset(self, request):
qs = super(UserAdminCustom, self).get_queryset(request)
return qs.filter(is_staff=False)

def get_readonly_fields(self, request, obj=None):
return ('id', 'created', 'modified')

# save_model() handle encrypt data on saving
def save_model(self, request, obj, form, change):
for field in form.changed_data:
if form.cleaned_data.get(field) is not None:
if field in user_profile_encrypt_fields:
encrypted_value = encrypt_string(form.cleaned_data.get(field))
setattr(obj, field, encrypted_value)
obj.save()


admin.site.register(User, UserAdminCustom)

自定义 UserAdminForm 供我解密数据,以便管理员在进行编辑或检查时可以看到数据是什么。解密后的数据能够正确显示在更改 View 上

当管理员在 Django 管理员更改 View 上编辑字段时,save_model() 将处理数据加密。

我当前的问题:

注释:

这些字段中的数据是存在的,所以我只讨论 django admin 上的编辑对象部分。

每当我尝试编辑任何字段并保存它(应该加密)时,该字段都会被加密并保存,但它下面的字段(它的实际加密数据)现在更改为实际数据(未加密)

在更改 View 上编辑 evt_address 并保存后

使用form = UserAdminForm时解密数据

enter image description here

注释掉 UserAdminCustom 上的# form = UserAdminForm,以便显示实际数据

enter image description here

我打印了getattr(self.instance, field)来查看加载django管理更改 View 时的加密数据,并得到以下4个加密字段:

web_1         | eth_address : gAAAAABeAcoI08bH2fQqJboZFxg6xn5RCxdRopllS6fDeyRmsC3qzsTXo88NVYOb58eeX5IXQpxqcGhbLr8wRRoWSKQsX5vLbPPhmWqUiqf0XYQvdWUhhgYxxMwwqgEOwU2OtJfkZ0p6
web_1 | eth_private_key : gAAAAABeAcoIp1V9sKNnL-dO-fWH1W1oM7hbqky44aRLchmTtvckaaZdaKuXo1xIIozx3xl40Y2Ct3YAyCOfkJJranKgTNDcVhndYdu5-awOuYpPCJKkSSia7IP_gWjLE91Gh8vsGnkn1iEkrLaho2ff0vVHS1QgGaJxji5m7cwCk0tqSp2AIeA=
web_1 | evt_address : gAAAAABeAcoIM3rywSgAPL611WUoWLJ9mqIgUHhZn8KDQd9hi9xHzgRri0EkoS_yBvwQyzdH72RWJRsDCs38oF9P8HHW_wFDWQ==
web_1 | evt_private_key : 1814067

因此,在编辑 evt_address 值并保存后,我的 evt_private_key 数据更改为 1814067

为什么会发生这种情况,我很困惑是什么导致了这种情况。

希望有人能帮助我

最佳答案

您在错误的抽象层上执行此操作。

请按照本指南创建一个自定义 Django 字段来为您处理加密/解密:https://docs.djangoproject.com/en/2.2/howto/custom-model-fields/

或者只是使用一些现有的解决方案,例如:https://github.com/foundertherapy/django-cryptographic-fields

关于python - Django Admin 使用 save_model() 加密更改(或保存)时某些字段的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59466161/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com