【问题标题】:django: Extending user model using one-to-one: how to save() Profile model's fieldsdjango:使用一对一扩展用户模型:如何保存()配置文件模型的字段
【发布时间】:2019-05-12 01:44:44
【问题描述】:

我有一个基本的 Django 应用程序,其中与 User 模型一起,我使用 一对一字段扩展了 Profile 模型。

模型.py

class Profile(models.Model):
  user = models.OneToOneField(User, on_delete=models.CASCADE,  null=True)
  profile_picture = models.ImageField(upload_to='customer_profile_images/%Y/%m/%d/', null=True, blank=True, verbose_name="Profile Picture")
  phone_number = models.CharField(null=True, blank=True, max_length=10)

  # no need for following two methods
  # def create_user_profile(sender, instance, created, **kwargs):
    # if created:
        # Profile.objects.get_or_create(user=instance)

  # post_save.connect(create_user_profile, sender=User)

  def __str__(self):
     return f'{self.user.first_name} {self.user.last_name}'

admin.py 我已经注册了 Profile 模型如下:

from myapp import Profile


class ProfileAdmin(admin.ModelAdmin):
list_display = ('user', 'phone_number')

admin.site.register(Profile, ProfileAdmin)

并且在 User 模型中成功创建了一个 Profile 模型。

在为用户创建新帐户时在views.py

class CustomerSignUpView(View):
def post(self, request):
    name_r = request.POST.get('customer_username')
    password_r = request.POST.get('customer_password')
    email_r = request.POST.get('customer_email')
    contact_number_r = request.POST.get('customer_contact_number')
    profile_picture_r = request.FILES['customer_profile_picture']

     # this is how i am saving contact number, profile picture for Profile model.

    if checkemail(email_r):
        c = User.objects.create_user(username=name_r, password=password_r, email=email_r)
        c.save()

        # add the following code
        p = Profile(user=c, phone_number=contact_number_r, profile_picture=profile_picture_r)
        p.save()       

        return render(request, 'catalog/customer_login.html')
    else:
        return render(request, 'catalog/customer_signup.html')

def get(self, request):
    return render(request, 'catalog/customer_signup.html')

但是,在注册页面创建新用户帐户时,我遇到以下错误:

我不明白如何使用 save() 方法保存 Profile 模型的那些新创建的字段。

更新:找到解决方案-

在views.py中,这就是我在配置文件模型中保存字段的方式

     p = Profile(user=c, phone_number=contact_number_r, profile_picture=profile_picture_r)
     p.save()

现在,每当我注册一个新用户时,用户名、头像和电话号码也会添加到个人资料模型中,即使在删除/更新个人资料详细信息期间,这些更改也会反映在用户和配置文件模型

以下链接对我的项目要求很有用:

http://books.agiliq.com/projects/django-orm-cookbook/en/latest/one_to_one.html

【问题讨论】:

  • 我只是想在写答案之前知道,您是在自定义管理员吗?如果没有,那么您不需要模型管理员。并且只使用create_or_update_user_profile 或使用create_user_profilesave_user_profile
  • 我正在为我创建的许多其他模型自定义管理面板,并且我已经尝试了您的解决方案..现在我只有一个 create_or_update_usere_profile() 方法,但错误仍然存​​在
  • 我认为您可以为所有现有用户对象创建虚拟用户配置文件。
  • simpleisbetterthancomplex.com/tutorial/2016/07/22/… 扩展用户配置文件是一个非常简单的解释,无需耗时且编码非常简单。希望你能这么快得到它
  • 是的,我从这个网站大量引用,但它没有显示任何代码来保存自定义配置文件模型中那些新创建的 profile_picture、dob 字段

标签: django django-models django-users django-signals


【解决方案1】:

首先,保存用户后不需要保存配置文件的实例:

 @receiver(post_save, sender=User)
  def save_user_profile(sender, instance, **kwargs):
    instance.profile.save()

删除上面的代码。要回答您的问题,如果未创建 User 实例,那么您不想创建配置文件实例,因此无需担心那部分。请将以下代码添加到您的 admin.py 以将管理员用户表单与配置文件一合并。

class ProfileInline(admin.StackedInline):    
    model = Profile
    can_delete = False
    verbose_name_plural = 'Profile'
    fk_name = 'user'

另外,建议您阅读this

您不应该直接从帖子中获取值。这不是一种安全的方式。要么使用基本表单并从 cleaned_data 字典中获取数据,要么使用 ModelForm。

我假设您是 Django 的新手,如果您不太沉迷于使用基于类的视图,建议您使用基于函数的视图。这对你来说很容易,你会看到所有的步骤。

关注this 一。如果不是this 将解决您的问题,因此您可以将您的代码调整为这个。

【讨论】:

  • 感谢您的即兴创作!能否也提供一个解决方案,在sign_up def函数时保存Profile模型的字段?
  • simpleisbetterthancomplex 网站使用表单来检索/保存配置文件模型中的数据,但是我不想为此使用表单。而且本教程从未显示位置和生物字段如何存储在 Profile 模型中
  • 那么您打算如何检索注册数据?即使您尝试从 get 获取值,表单也是唯一的方法,如果您想将它们写入数据库,它应该是一个 post 请求。
  • 我附上的链接清楚地提到了将配置文件连接到用户的步骤。不知道你在说什么。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-08-07
  • 2016-08-16
  • 2017-03-19
  • 2017-07-14
  • 2017-06-18
  • 1970-01-01
  • 2017-10-20
相关资源
最近更新 更多