如何扩展 django oscar 客户模型字段?

Posted

技术标签:

【中文标题】如何扩展 django oscar 客户模型字段?【英文标题】:How do I extend the django oscar customer models fields? 【发布时间】:2016-11-09 21:27:21 【问题描述】:

如何扩展 django-oscar 客户模型字段?我已扩展注册表以包含更多字段,apps/customer/forms.py

class EmailUserCreationForm(forms.ModelForm):
    email = forms.EmailField(label=_('Email address'))
    password1 = forms.CharField(
        label=_('Password'), widget=forms.PasswordInput,
        validators=password_validators)
    password2 = forms.CharField(
        label=_('Confirm password'), widget=forms.PasswordInput)

    #### The extra fields I want to add #####

    first_name = forms.CharField(label=_('First name'))
    last_name = forms.CharField(label=_('Last name'))
    business_name = forms.CharField(label=_('Business name'))
    business_address = forms.CharField(label=_('Business address'))
    city = forms.CharField(label=_('City'))

我还在apps/customer/abstract_models.py 中扩展了[AbstractUser][1] 的字段。

class AbstractUser(auth_models.AbstractBaseUser,
                   auth_models.PermissionsMixin):
    """
    An abstract base user suitable for use in Oscar projects.

    This is basically a copy of the core AbstractUser model but without a
    username field
    """
    email = models.EmailField(_('email address'), unique=True)
    first_name = models.CharField(
        _('First name'), max_length=255, blank=True)
    last_name = models.CharField(
        _('Last name'), max_length=255, blank=True)
    is_staff = models.BooleanField(
        _('Staff status'), default=False,
        help_text=_('Designates whether the user can log into this admin '
                    'site.'))
    is_active = models.BooleanField(
        _('Active'), default=True,
        help_text=_('Designates whether this user should be treated as '
                    'active. Unselect this instead of deleting accounts.'))
    date_joined = models.DateTimeField(_('date joined'),
                                       default=timezone.now)
    #######################################
    # Additional user fields I have added #
    #######################################
    business_name = models.CharField(
        _('Business name'), max_length=255, blank=True)
    business_address = models.CharField(
        _('Business address'), max_length=255, blank=True)
    city = models.CharField(

但是,当创建用户时,其他字段不会保存到数据库中。有没有更好的方法来扩展客户模型以包含我不知道的其他字段?

当我尝试在 shell 中调试时,我遇到了模型不可调用的问题:

>>> from apps.customer.abstract_models import *
>>> mg = UserManager()
>>> mg.create_user('testemail@test.com', 'testpassword', buisness_name='test_business')
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "<my_working_dir>/apps/customer/abstract_models.py", line 34, in create_user
    last_login=now, date_joined=now, **extra_fields)
TypeError: 'NoneType' object is not callable

我不确定django oscar's 文档中给出的说明是否有效,因为这是用于自定义方法,而不是模型上的字段。

任何帮助将不胜感激。

编辑:

INSTALLED_APPS = INSTALLED_APPS + get_core_apps(
    ['apps.shipping',
     'apps.checkout',
     'apps.partner',
     'apps.catalogue',
     'apps.customer',
     ])


AUTH_USER_MODEL = 'customer.User'

【问题讨论】:

完全可以在模型中添加字段。您的问题是您的应用程序没有被加载。为了帮助我们确定问题,请发布:您在何处创建此新代码的详细信息(与您的项目根目录相关的文件/目录)、INSTALLED_APPSAUTH_USER_MODEL 设置。 我会扩展地址模型而不是用户模型。地址将具有 is_default 属性和用户的外键。 【参考方案1】:

我可以看到一些问题,解决这些问题有望解决您的问题:

    AbstractUser 的子类移动到apps/customer/models.py,这是Django 查找模型的地方。您已将其放在apps/customer/abstract_models.py 中,这是用于存储模型的非标准位置(Oscar 仅对抽象模型执行此操作 - 您不应该自己镜像此位置)。 Django 不会在那里找到它们。

    将你的类名改为User而不是AbstractUser,因为你的最终模型不是抽象的。您还在AUTH_USER_MODEL 中指定customer.User - 这两者需要匹配。

    您在上面发布的模型类不完整,因此我们无法判断 - 但请确保它在 Meta 类中不包含 abstract = True

    运行manage.py makemigrations,它应该为您的新用户模型创建迁移(如果没有,那么您的应用程序结构仍然存在问题)。 (下次运行manage.py migrate)。

    不要忘记在models.py:from oscar.apps.customer.models import * 底部导入其余(核心)客户模型。没有这些,您将失去核心客户应用程序中的所有其他模型。

您还应该注意documentation 中有关更改用户模型的警告(强调我的):

更改 AUTH_USER_MODEL 对您的数据库结构有很大影响。 它会更改可用的表,并且会影响 外键和多对多关系的构建。如果你 打算设置 AUTH_USER_MODEL,您应该在创建任何 迁移或第一次运行 manage.py migrate。

不支持在创建表后更改此设置 通过 makemigrations 并且将导致您必须手动修复您的 架构,从旧用户表中移植您的数据,并且可能手动 重新应用一些迁移。

【讨论】:

我已经执行了这些更改,但现在我遇到了身份验证问题 |用户模型与我自定义的客户用户模型冲突。之前已创建帐户以将 AUTH_USER_MODEL 属性更新为 customer.User 这是更改用户模型的固有风险 - 在现有数据库上并不容易或不推荐。我在答案中添加了文档中的一些警告-除此之外无法真正帮助您。 我可以在类中使用 = get_user_model() 设置模型,然后在其上添加字段吗? 不,我不这么认为。您可以尝试将模型的 Meta 类设置为使用与以前相同的表名 (db_table = 'auth_user'),然后查看迁移是否有效。如果没有,那么您要么需要手动修复表,要么考虑另一种方法(例如,profile model)。 好的,我手动修复了表,现在用户已经转移到新的auth模型了。

以上是关于如何扩展 django oscar 客户模型字段?的主要内容,如果未能解决你的问题,请参考以下文章

如何向 django-oscar 添加新视图

如何正确扩展 django 用户模型

如何将 Stripe 支付网关与 Django Oscar 集成?

如何创建 django-oscar 产品类作为数据迁移

Django - 如何在不修改的情况下扩展 3rd 方模型

如何验证 Django Oscar 中的帐单地址信息?