【问题标题】:Django - Customizeable UserProfileDjango - 可定制的用户配置文件
【发布时间】:2011-06-09 15:28:41
【问题描述】:

所以我在 Django 中有一个 UserProfile,其中包含整个项目所需的某些字段 - 生日、居住地等 - 它还包含许多实际上并不重要的信息逻辑去 - 家乡,关于我等。我试图让我的项目比我自己的项目更灵活并适用于更多情况,我想让项目实例的管理员可以添加任何字段他们喜欢一个 UserProfile 而不必直接修改模型。也就是说,我希望新实例的管理员能够根据用户的特定需求动态创建用户的新属性。由于 ORM 的性质,这可能吗?

【问题讨论】:

  • 我宁愿有另一个带有key:value 对的表,其中key 描述它的属性类型(网站、地址),value 类似于“google.com”、“Mountain查看”等,并将这些对与UserProfile联系起来。

标签: django database-design user-profile


【解决方案1】:

一个简单的解决方案是创建一个名为 UserAttribute 的新模型,该模型具有一个键和一个值,并将其链接到 UserProfile。然后你可以将它用作 django-admin 中的内联。这将允许您通过管理员向 UserProfile 添加任意数量的新属性:

models.py

class UserAttribute(models.Model):
    key = models.CharField(max_length=100, help_text="i.e. Age, Name etc")
    value = models.TextField(max_length=1000)
    profile = models.ForeignKey(UserProfile)

admin.py

class UserAttributeInline(admin.StackedInline):
    model = UserAttribute

class UserProfile(admin.ModelAdmin):
    inlines = [UserAttibuteInline,]

这将允许管理员添加一长串属性。限制是您不能对输入进行任何验证(除了确保它是有效文本之外),您还仅限于可以用简单的英语描述的属性(即您将无法对它们执行太多登录) 并且您将无法真正比​​较 UserProfile 之间的属性(无论如何都没有大量数据库命中)

【讨论】:

  • +1 同意,这是database normalization 问题不是 Django ORM。
  • 是的,我在 stackoverflow 的其他地方看到过这个建议,虽然如果我只想存储字符串值,它工作得很好,但如果你想,比如说,有具有适当验证的电子邮件字段,或根本没有日期时间字段。
  • 那么您在谈论动态表单字段。实际上,我只是在 convore 上问了一个关于这个的问题,因为我自己也在想这个问题:convore.com/django-community/dynamic-formsform-building
【解决方案2】:

您可以以序列化状态存储其他数据。这可以为您节省一些数据库命中并稍微简化您的数据库结构。如果您打算仅将数据用于显示目的,这可能是最佳选择。

示例实现(未测试)::

import yaml
from django.db import models

class UserProfile(models.Model):
    user = models.OneToOneField('auth.User', related_name='profile')
    _additional_info = models.TextField(default="", blank=True)

    @property
    def additional_info(self):
        return yaml.load(self._additional_info)
    @additional_info.setter
    def additional_info(self, user_info_dict):
        self._additional_info = yaml.dump(user_info_dict)

当您分配给profile.additional_info 时,比如说,一个字典,它会被序列化并存储在_additional_info 中(不要忘记稍后保存实例)。然后,当你访问additional_info 时,你会得到那个 python 字典。

我猜,你也可以写一个自定义字段来处理这个。


更新(根据您的评论):

因此,这里的实际问题似乎是如何为用户配置文件自动创建和验证表单。 (不管你是使用序列化选项还是复杂的数据结构,它仍然存在。)

既然您可以轻松创建动态表单[1],那么主要问题是如何验证它们。

考虑一下...管理员无论如何都必须为每个自定义字段指定验证器(或字段类型),对吧?所以你需要某种配置选项——比如,

CUSTOM_PROFILE_FIELDS = (
    {
        'name': 'user_ip',
        'validators': ['django.core.validators.validate_ipv4_address'],
        },
    )

然后,当您初始化表单时,您可以根据此设置定义字段及其验证器。

[1] 另请参阅 Jacob Kaplan-Moss 关于动态表单生成的 this post。不过,它不处理验证。

【讨论】:

  • 我实际上已经使用 JSON 编写了这个系统,如果您想自动创建表单以及模型中的数据,这将是一个巨大的痛苦,特别是如果您需要正确的验证器。绝对可以创建基于附加信息中的内容动态增长的表单,但获得验证的表单字段要困难得多。我不会说不可能,但我只是不知道有什么办法。
  • 非常感谢您的更新,等我结束这次会议后,我会试一试。
猜你喜欢
  • 2017-02-10
  • 2023-03-29
  • 2013-09-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-04
  • 2012-08-01
相关资源
最近更新 更多