【问题标题】:Django AbstractBaseUser MultipleChoiceFieldDjango AbstractBaseUser MultipleChoiceField
【发布时间】:2021-01-20 17:04:02
【问题描述】:

我已经使用 AbstractBaseUser 创建了一个自定义用户模型,如下所示:

class CustomUser(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField(_('email address'), unique=True)
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)
    preference = models.CharField(max_length=400)
    date_joined = models.DateTimeField(default=timezone.now)

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['first_name', 'last_name', 'preference']

    objects = CustomUserManager()

    def __str__(self):
        return self.email

对于首选项字段,我不想要一个字符字段,而是创建一个 MultipleChoiceField 并且当用户注册以从选项中选择他/她想要的内容时。有没有一种简单的方法可以做到这一点? 我有一个类似的表格,用于不同的目的:

class CategoryForm(forms.Form):
    def __init__(self, *args, **kwargs):
        categories = kwargs.pop("Category")
        super(CategoryForm, self).__init__(*args, **kwargs)
        self.fields["Category"] = forms.MultipleChoiceField(choices=categories, label='Click this to select categories')

编辑

class CustomUser(AbstractBaseUser, PermissionsMixin):
    category_list = pickle.load(open("/home/anonymous/Documents/Diploma-Recommender/Recommendation/Dataset"
                                     "/category_list.pickle", "rb"))
    email = models.EmailField(_('email address'), unique=True)
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)
    category_tuple = ((),)
    for j in category_list:
        category_tuple = category_tuple + ((j, j),)
    category_tuple = list(category_tuple)
    category_tuple.pop(0)
    category_tuple = tuple(category_tuple)
    preference = ArrayField(
        models.CharField(choices=category_tuple, null=True, max_length=50, blank=True, default=None),
    )

    date_joined = models.DateTimeField(default=timezone.now)

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['first_name', 'last_name', 'preference']

    objects = CustomUserManager()

    def __str__(self):
        return self.email

【问题讨论】:

    标签: python django


    【解决方案1】:

    如果您使用的是 postgreSQL,我建议您在模型中使用 ArrayField(您应该这样做!)。这将实现您在模型字段中进行多项选择的目标。

    from django.contrib.postgres.fields import ArrayField
    
    class CustomUser(AbstractBaseUser, PermissionsMixin):
        CATEGORY_1 = 'Category_1'
        CATEGORY_2 = 'Category_2'
        CATEGORY_3 = 'Category_3'
    
        CATEGORY_TYPE_CHOICES = [
            (CATEGORY_1, 'Category_1'),
            (CATEGORY_2, 'Category_2'),
            (CATEGORY_3, 'Category_3')
        ]
    
         category = ArrayField(
            max_length=10,
            choices=CATEGORY_TYPE_CHOICES,
            null=True,
            default=None,
            blank=True
        )
    

    在此处阅读更多信息:Django Model MultipleChoice

    【讨论】:

    • 我非常喜欢您的解决方案,并为此感谢。我的问题是用户在注册时如何选择这些类别?
    • 这里我也觉得:category = models.ArrayField 你的意思是 category = ArrayField based on your import 你确定这是正确的语法吗?
    • 你能检查我的编辑吗?我想这就是你给我看的。但是现在在 html 中,我如何向用户显示可用选项?
    • 我认为如果我们要使用 ArrayField - stackoverflow.com/questions/31426010/…,这就是您所需要的。请参阅第二个答案,它关于管理面板,但应适用于所有表单。不过,我只是在想,在这里使用 ManyToMany 字段对您来说可能会更容易。我经常在这种情况下使用它。类别可以是另一个模型。在User 模型上,您可以拥有categories,这将是具有类别的M2M。然后只需 user.categories.add(category) 添加首选项。然后,您也可以动态更改和删除这些类别。
    【解决方案2】:

    如果您的多项选择是 active diactive 你可以像这样指定:

    CHOICES = (('one','one'), ('two','two') ...)
    preference = models.CharField(max_length=400, choices = CHOICES)
    

    如果您想获得性别或一些有限的选择,则此方法有效,但是如果您的选择来自不同的模型,例如类别,并且如果选择的数量为 1 ForeignKey 则有模型 Category 并且如果它更多超过 1 个在您的用户模型中使用 ManyToMany 关系

    如果你使用ModelForm django 会为你处理。

    【讨论】:

    • 我共有 o 61 个类别,用户可以选择任意多个类别。当他注册并创建用户时,我希望有一个包含所有可用类别的下拉列表,然后进行选择。正如我在代码中展示的那样,我已经设法创建了这样的表单。如果可能的话,我想使用该表格进行用户注册。
    • 不,如果您不将模型 preference 中的该字段更改为 manytomany,则在保存时会出错。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-03
    • 1970-01-01
    • 2017-09-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多