Django - Как расширить Custom User, используя CreateView - PullRequest
0 голосов
/ 22 апреля 2019

Я хочу создать форму регистрации пользователя, используя CreateView. Но я не знаю, как объединить модель пользователя с моделью профиля в view.py

Моя окружающая среда · Django2.2

Вот код, который я написал:

▪️model.py

class User(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField(_('email address'), unique=True)
    first_name = models.CharField(_('first name'), max_length=30, blank=True)
    last_name = models.CharField(_('last name'), max_length=30, blank=True)

class Profile(models.Model):
    user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    gender = models.CharField(max_length=20, blank=True)

▪️form.py

class UserCreateForm(UserCreationForm):

    class Meta:
        model = User
        if User.USERNAME_FIELD == 'email':
            fields = ('email',)
        else:
            fields = ('username', 'email')

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        for field in self.fields.values():
            field.widget.attrs['class'] = 'form-control'

class ProfileForm(forms.ModelForm):
    CHOICES = (
        ('female', 0,),
        ('male', 1,),
        ('not_applicable', 2,)
    )
    gender = forms.ChoiceField(widget=forms.RadioSelect, choices=CHOICES, required=False)

▪️View.py

from django.views import generic
from .forms import UserCreateForm

class UserCreate(generic.CreateView):
    template_name = 'accounts/create.html'
    form_class = UserCreateForm

    def form_valid(self, form):
        user = form.save(commit=False)
        user.is_active = False
        user.save()

        current_site = get_current_site(self.request)
        domain = current_site.domain
        context = {
            'protocol': 'https' if self.request.is_secure() else 'http',
            'domain': domain,
            'token': dumps(user.pk),
            'user': user,
        }

        subject_template = get_template('accounts/mail/create/subject.txt')
        subject = subject_template.render(context)

        message_template = get_template('accounts/mail/create/message.txt')
        message = message_template.render(context)

        user.email_user(subject, message)
        return redirect('accounts:user_create_done')

▪️create.html

<form action="" method="POST">
    {{ form.non_field_errors }}
            {% for field in form %}
                    <p>{{ field }} {{ field.errors }}</p>
            {% endfor %}
    {% csrf_token %}
    <button type="submit" class="button-submit">submit</button>
</form>

Однако может отображаться только столбец пользователя (только электронная почта, пароль). Но я хотел бы показать столбец пользователя и столбец профиля (адрес электронной почты, пароль, имя, фамилия, пол).

Возможно ли это?

Ответы [ 2 ]

0 голосов
/ 22 апреля 2019

Список fields в Meta из UserCreationForm должен содержать все поля, которые нужно показать.Вы также должны добавить поля профиля в UserCreationFrom и вручную обновить профиль.Также, пожалуйста, измените имя вашей формы, чтобы отличить его от UserCreateForm.

в django. Также убедитесь, что при вызове user.profile для пользователя создается профиль.

# models.py
# add the below line in the end of the file.
User.profile = property(lambda u: Profile.objects.get_or_create(user=u)[0])

Обновите вашу форму.

# forms.py

class CustomUserCreateForm(UserCreationForm):
    CHOICES = (
        ('female', 0,),
        ('male', 1,),
        ('not_applicable', 2,)
    )
    gender = forms.ChoiceField(widget=forms.RadioSelect, choices=CHOICES, required=False)

    class Meta:
        model = User
        if User.USERNAME_FIELD == 'email':
            fields = ('email',)
        else:
            fields = ('username', 'email')
        fields += ('password', 'first_name', 'last_name', 'gender')

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        for field in self.fields.values():
            field.widget.attrs['class'] = 'form-control'

По вашему мнению, вы можете сохранить значение gender в user.profile.

class UserCreate(generic.CreateView):
    template_name = 'accounts/create.html'
    form_class = CustomUserCreateForm

    def form_valid(self, form):
        user = form.save(commit=False)
        user.is_active = False
        user.save()

        # get the value of gender and save to user.profile
        gender = form.cleaned_data.get("gender")
        profile = user.profile  # this will get_or_create the profile instance
        profile.gender = gender
        profile.save()

        current_site = get_current_site(self.request)
        domain = current_site.domain
        context = {
            'protocol': 'https' if self.request.is_secure() else 'http',
            'domain': domain,
            'token': dumps(user.pk),
            'user': user,
        }

        subject_template = get_template('accounts/mail/create/subject.txt')
        subject = subject_template.render(context)

        message_template = get_template('accounts/mail/create/message.txt')
        message = message_template.render(context)

        user.email_user(subject, message)
        return redirect('accounts:user_create_done')
0 голосов
/ 22 апреля 2019

Вы должны наследовать AbstractBaseUser в своем собственном CustomUserModel, добавить дополнительные поля, которые вы хотите, а затем также переопределить AUTH_USER_MODEL=yourapp.CustomUserModel в вашем settings.py файле

Может быть стоит взглянуть и на это .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...