1

I have created a custom user model with AbstractBaseUser like this:

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

For the preference field i don't want a char field, but to create a MultipleChoiceField and when a user sign up to choose what he/she wants from the choices. Is there a simple way to do this? I have a similar form which i used for different purpose:

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')

EDIT

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

2 Answers2

0

if your multiple choice is sth like active diactive you can just specify those like this :

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

this works if you want to get the gender or some limited choices , but if your choices is from different model like category and there is a model Category if the number of choices is 1 ForeignKey and if it is more than 1 use ManyToMany relation in your User model

and if you use ModelForm django handles it for you.

  • I have a total o 61 categories , and user can choose as many categories as he wants. When he register, and user is created i want to have a dropdown list with alla the available categories, and then to choose. I have manage to create such a form, as i show at my code. If it is possible i want to use that form for the user registration. – Nikos tzagkarakis Jan 20 '21 at 17:34
  • No, if you dont change that field in you model `preference ` to a manytomany you get error when you want to save it. – Roohollah Mozaffari Jan 20 '21 at 19:18
0

I would recommend using an ArrayField in your model if you are using postgreSQL (which you should be!). This will accomplish your goal of multiple choices in a model field.

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
    )

Read more here: Django Model MultipleChoice

twrought
  • 636
  • 5
  • 9
  • I like a lot your solution, and thanks for that. My question is how the user will select these categories at registration time? – Nikos tzagkarakis Jan 20 '21 at 17:35
  • I also think here: category = models.ArrayField your mean category = ArrayField based on your import Are you sure this is the correct syntax? – Nikos tzagkarakis Jan 20 '21 at 17:58
  • Can you please check my edit? I think that is what you show me. But now at the html, how can i show the user the available options? – Nikos tzagkarakis Jan 20 '21 at 18:28
  • 1
    I think this is what you need if we are going with ArrayField - https://stackoverflow.com/questions/31426010/better-arrayfield-admin-widget. See second answer, its about admin panel but should apply to all forms. I was just thinking though, how it might be easier for you to use a ManyToMany field here. I often use that in such a context. Category can be another model. On the ```User``` model, you could have ```categories``` which would be a M2M with category. Then just ```user.categories.add(category)``` to add a preference. Then, you can dynamically change and delete these categories as well. – twrought Jan 20 '21 at 18:55