gpt4 book ai didi

python - 在自定义用户的配置文件中发现不需要的随机值

转载 作者:行者123 更新时间:2023-12-01 01:40:27 25 4
gpt4 key购买 nike

我正在关注https://docs.djangoproject.com/en/2.1/topics/auth/customizing/#a-full-example ,以电子邮件作为用户名创建用户。

我还使用个人资料表创建一对一关系。 profile 表包含 API key 列

我查看了user 表和profile 表。他们俩看起来都很好。如果我在 user 表中有 3 条记录,那么在 profile 表中只有 3 条记录,因为它们是一对一的关系。

<小时/>

但是,当我登录管理页面时。事情听起来不太对劲。每个用户都与 2 个 API key 相关联。第一个 API key 似乎是随机生成的值,另一个 API key 是来自数据库的有效 API key 。

enter image description here

这是当前的数据库。

snapweb=# select * from accounts_myuser;
id | password | last_login | email | is_active | is_admin
----+--------------------------------------------------------------------------------+-------------------------------+
2 | pbkdf2_sha256$120000$w7OlH | | yccheok@yahoo.com | t | f
1 | pbkdf2_sha256$120000$tWA6Y | 2018-08-21 05:07:28.391689+00 | root@root.com | t | t
3 | pbkdf2_sha256$120000$TkKAE | | yancheng.cheok@gmail.com | t | f
(3 rows)

snapweb=# select * from accounts_profile;
id | api_key | user_id
----+--------------------------------------+---------
1 | d6ee9b31-6847-4b7d-8151-98b133f21c42 | 1
2 | c6f3718e-41ee-4759-984a-63c405b32fc4 | 2
3 | 10c64d48-416f-4fd7-b01d-4328d2536ea2 | 3
(3 rows)

现在,管理页面中显示的值为

API KEY: 6cb1b77f-6ab0-464d-9176-d0ed20402b8c: API KEY: 10c64d48-416f-4fd7-b01d-4328d2536ea2 

当你刷新页面时,它会变成

API KEY: b4a07773-a3e0-4fcc-bf5c-245935cd0687: API KEY: 10c64d48-416f-4fd7-b01d-4328d2536ea2 
<小时/>

你知道为什么会出现这种奇怪的行为吗?

这是代码

模型.py
import uuid
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.db import models
from django.contrib.auth.models import (
BaseUserManager, AbstractBaseUser
)

class MyUserManager(BaseUserManager):
def create_user(self, email, password=None):
"""
Creates and saves a User with the given email and
password.
"""
if not email:
raise ValueError('Users must have an email address')

user = self.model(
email=self.normalize_email(email),
)

user.set_password(password)
user.save(using=self._db)
return user

def create_superuser(self, email, password):
"""
Creates and saves a superuser with the given email and
password.
"""
user = self.create_user(
email,
password=password,
)
user.is_admin = True
user.save(using=self._db)
return user


class MyUser(AbstractBaseUser):
email = models.EmailField(
verbose_name='email address',
max_length=255,
unique=True,
)
is_active = models.BooleanField(default=True)
is_admin = models.BooleanField(default=False)

objects = MyUserManager()

USERNAME_FIELD = 'email'

def __str__(self):
return self.email

def has_perm(self, perm, obj=None):
"Does the user have a specific permission?"
# Simplest possible answer: Yes, always
return True

def has_module_perms(self, app_label):
"Does the user have permissions to view the app `app_label`?"
# Simplest possible answer: Yes, always
return True

@property
def is_staff(self):
"Is the user a member of staff?"
# Simplest possible answer: All admins are staff
return self.is_admin


class Profile(models.Model):
user = models.OneToOneField(MyUser, on_delete=models.CASCADE)
api_key = models.UUIDField(default=uuid.uuid4, editable=False, unique=True)

def __str__(self):
return 'API KEY: ' + str(self.api_key)


@receiver(post_save, sender=MyUser)
def create_or_update_user_profile(sender, instance, created, **kwargs):
if created:
Profile.objects.create(user=instance)
instance.profile.save()

admin.py
from django import forms
from django.contrib import admin
from django.contrib.auth.models import Group
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from django.contrib.auth.forms import ReadOnlyPasswordHashField

from accounts.models import MyUser
from accounts.models import Profile

class UserCreationForm(forms.ModelForm):
"""A form for creating new users. Includes all the required
fields, plus a repeated password."""
password1 = forms.CharField(label='Password', widget=forms.PasswordInput)
password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput)

class Meta:
model = MyUser
fields = ('email',)

def clean_password2(self):
# Check that the two password entries match
password1 = self.cleaned_data.get("password1")
password2 = self.cleaned_data.get("password2")
if password1 and password2 and password1 != password2:
raise forms.ValidationError("Passwords don't match")
return password2

def save(self, commit=True):
# Save the provided password in hashed format
user = super().save(commit=False)
user.set_password(self.cleaned_data["password1"])
if commit:
user.save()
return user


class UserChangeForm(forms.ModelForm):
"""A form for updating users. Includes all the fields on
the user, but replaces the password field with admin's
password hash display field.
"""
password = ReadOnlyPasswordHashField()

class Meta:
model = MyUser
fields = ('email', 'password', 'is_active', 'is_admin')

def clean_password(self):
# Regardless of what the user provides, return the initial value.
# This is done here, rather than on the field, because the
# field does not have access to the initial value
return self.initial["password"]


class MyCustomUserInline(admin.StackedInline):
model = Profile
can_delete = True
verbose_name = Profile


class UserAdmin(BaseUserAdmin):
# The forms to add and change user instances
form = UserChangeForm
add_form = UserCreationForm

# The fields to be used in displaying the User model.
# These override the definitions on the base UserAdmin
# that reference specific fields on auth.User.
list_display = ('email', 'is_admin')
list_filter = ('is_admin',)
fieldsets = (
(None, {'fields': ('email', 'password')}),
('Permissions', {'fields': ('is_admin',)}),
)
# add_fieldsets is not a standard ModelAdmin attribute. UserAdmin
# overrides get_fieldsets to use this attribute when creating a user.
add_fieldsets = (
(None, {
'classes': ('wide',),
'fields': ('email', 'password1', 'password2')}
),
)
search_fields = ('email',)
ordering = ('email',)
filter_horizontal = ()

inlines = (MyCustomUserInline, )

# Now register the new UserAdmin...
admin.site.register(MyUser, UserAdmin)
# ... and, since we're not using Django's built-in permissions,
# unregister the Group model from admin.
admin.site.unregister(Group)
<小时/>

更新

更改代码后

class Profile(models.Model):
user = models.OneToOneField(MyUser, on_delete=models.CASCADE)
api_key = models.UUIDField(default=uuid.uuid4, editable=False, unique=True)

def __str__(self):
return 'API KEY: ' + str(self.api_key)

class Profile(models.Model):
user = models.OneToOneField(MyUser, on_delete=models.CASCADE)
api_key = models.UUIDField(default=uuid.uuid4, editable=False, unique=True)

def __str__(self):
if hasattr(self, 'user'):
return 'API KEY -> ' + str(self.api_key)
else:
return ''

我知道如何能够部分“消除”这个问题(不知道为什么仍然有一个双冒号:)

enter image description here

现在,问题又回到了,为什么有一个 Profile 对象,而没有首先创建 MyUser 对象?怎样才能彻底消除问题呢? (甚至没有显示双冒号 :)

最佳答案

您必须更改 InlineModelAdmin 中的属性 verbose_name = Profile 并改用字符串编辑:此外,您应该让函数 __str__ 像以前一样:

class MyCustomUserInline(admin.StackedInline):
model = Profile
can_delete = True
verbose_name = "profile"

def __str__(self):
return 'API KEY: ' + str(self.api_key)

这样,结果应该是:

Profile: API KEY: 10c64d48-416f-4fd7-b01d-4328d2536ea2

为什么你的 key 会被随机复制?

通过 verbose_name = Profile,Django 使用类 Profile 作为行的名称。具有 default 属性的字段已预先填充。在本例中,api_key 为:default=uuid.uuid4

关于python - 在自定义用户的配置文件中发现不需要的随机值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51942246/

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