[django] django-allauth를 사용할 때 사용자 프로필을 사용자 지정하는 방법

django-allauth 앱이있는 django 프로젝트가 있습니다. 가입시 사용자로부터 추가 데이터를 수집해야합니다. 여기 에서 비슷한 질문을 보았지만 불행히도 아무도 프로필 사용자 정의 부분에 대답하지 않았습니다.

을 위해 제공되는 설명서django-allauth :

ACCOUNT_SIGNUP_FORM_CLASS(= None)

‘myapp.forms.SignupForm’사용자에게 추가 입력 (예 : 뉴스 레터 가입, 생년월일)을 요청하기 위해 가입 중에 사용되는 사용자 지정 양식 클래스 (예 :)를 가리키는 문자열 입니다. 이 클래스는‘save’ 새로 가입 한 사용자를 유일한 매개 변수로 받아들이 메서드를 .

나는 django를 처음 접했고 이것으로 어려움을 겪고 있습니다. 누군가 이러한 사용자 지정 양식 클래스의 예를 제공 할 수 있습니까? 내가 좋아하는 사용자 개체에 대한 링크와 함께뿐만 아니라 모델 클래스를 추가해야합니까 ?



답변

가입하는 동안 사용자에게 이름 / 성을 묻고 싶다고 가정합니다. 이러한 필드를 다음과 같이 자신의 양식에 넣어야합니다.

class SignupForm(forms.Form):
    first_name = forms.CharField(max_length=30, label='Voornaam')
    last_name = forms.CharField(max_length=30, label='Achternaam')

    def signup(self, request, user):
        user.first_name = self.cleaned_data['first_name']
        user.last_name = self.cleaned_data['last_name']
        user.save()

그런 다음 설정에서 다음 양식을 가리 킵니다.

ACCOUNT_SIGNUP_FORM_CLASS = 'yourproject.yourapp.forms.SignupForm'

그게 다야.


답변

pennersr에서 제안한 솔루션을 사용하여 DeprecationWarning을 받았습니다.

DeprecationWarning: The custom signup form must offer a def signup(self, request, user) method DeprecationWarning)

이것은 버전 0.15부터 부터 def signup (request, user) 메소드를 위해 저장 메소드가 더 이상 사용되지 입니다.

따라서이를 해결하려면 예제 코드는 다음과 같아야합니다.

class SignupForm(forms.Form):
    first_name = forms.CharField(max_length=30, label='Voornaam')
    last_name = forms.CharField(max_length=30, label='Achternaam')

    def signup(self, request, user):
        user.first_name = self.cleaned_data['first_name']
        user.last_name = self.cleaned_data['last_name']
        user.save()


답변

다음은 몇 가지 다른 답변을 결합하여 저에게 효과적이었습니다 (그 중 어느 것도 100 % 완전하고 DRY가 아닙니다).

에서 yourapp/forms.py:

from django.contrib.auth import get_user_model
from django import forms

class SignupForm(forms.ModelForm):
    class Meta:
        model = get_user_model()
        fields = ['first_name', 'last_name']

    def signup(self, request, user):
        user.first_name = self.cleaned_data['first_name']
        user.last_name = self.cleaned_data['last_name']
        user.save()

그리고 settings.py:

ACCOUNT_SIGNUP_FORM_CLASS = 'yourapp.forms.SignupForm'

이렇게하면 DRY가되도록 모델 양식을 사용하고 새로운 def signup. 퍼팅을 시도 'myproject.myapp.forms.SignupForm'했지만 어떻게 든 오류가 발생했습니다.


답변

@ Shreyas : 아래 솔루션은 가장 깨끗하지는 않지만 작동합니다. 더 이상 정리할 제안이 있으면 알려주십시오.

기본 사용자 프로필에 속하지 않는 정보를 추가하려면 먼저 yourapp / models.py에서 모델을 만듭니다. 그것에 대해 더 배우려면 일반 django 문서를 읽으십시오.

from django.db import models

class UserProfile(models.Model):
    user = models.OneToOneField(User, related_name='profile')
    organisation = models.CharField(organisation, max_length=100, blank=True)

그런 다음 yourapp / forms.py에서 양식을 만듭니다.

from django import forms

class SignupForm(forms.Form):
    first_name = forms.CharField(max_length=30, label='Voornaam')
    last_name = forms.CharField(max_length=30, label='Achternaam')
    organisation = forms.CharField(max_length=20, label='organisation')

    def signup(self, request, user):
        user.first_name = self.cleaned_data['first_name']
        user.last_name = self.cleaned_data['last_name']
        # Replace 'profile' below with the related_name on the OneToOneField linking back to the User model
        up = user.profile
        up.organisation = self.cleaned_data['organisation']
        user.save()
        up.save()


답변

당신에 users/forms.py당신은 넣어 :

from django.contrib.auth import get_user_model
class SignupForm(forms.ModelForm):
    class Meta:
        model = get_user_model()
        fields = ['first_name', 'last_name']
    def save(self, user):
        user.save()

settings.py에 다음을 입력합니다.

ACCOUNT_SIGNUP_FORM_CLASS = 'users.forms.SignupForm'

이런 식으로 다중 사용자 모델 필드 정의로 DRY 원칙을 어 기지 않습니다.


답변

나는 많은 다른 튜토리얼을 시도했고 그들 모두는 무언가를 놓치고 불필요한 코드를 반복하거나 이상한 일을하고 있습니다. 벨로우는 내가 찾은 모든 옵션을 결합하는 솔루션을 따르고 작동하고 있습니다. 이미 프로덕션에 넣었지만 이미했습니다. 양식 내부에 프로필을 만들지 않기 위해 Users에 첨부 한 함수 내에서 first_name과 last_name을받을 것으로 예상하기 때문에 여전히 저를 설득하지 못했지만, 그럴 수는 없었습니다.

Models.py

class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    bio = models.TextField(max_length=500, blank=True)
    nationality = models.CharField(max_length=2, choices=COUNTRIES)
    gender = models.CharField(max_length=1, choices=GENDERS)

def __str__(self):
    return self.user.first_name


@receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
    if created:
        Profile.objects.create(user=instance)

@receiver(post_save, sender=User)
def save_user_profile(sender, instance, **kwargs):
    instance.profile.save()

Forms.py

class SignupForm(forms.ModelForm):
    first_name = forms.CharField(max_length=100)
    last_name = forms.CharField(max_length=100)

    class Meta:
        model = Profile
        fields = ('first_name', 'last_name', 'nationality', 'gender')

    def signup(self, request, user):
        # Save your user
        user.first_name = self.cleaned_data['first_name']
        user.last_name = self.cleaned_data['last_name']
        user.save()

        user.profile.nationality = self.cleaned_data['nationality']
        user.profile.gender = self.cleaned_data['gender']
        user.profile.save()

Settings.py

ACCOUNT_SIGNUP_FORM_CLASS = 'apps.profile.forms.SignupForm'


답변

#models.py

from django.conf import settings

class UserProfile(models.Model):
    user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    image = models.ImageField(default='users/default.png', upload_to='users')
    fields = models.ForeignKey('Field' ,null=True ,on_delete=models.SET_NULL)
    category = models.ForeignKey('Category' ,null=True ,on_delete=models.SET_NULL)
    description = models.TextField()
    interests = models.ManyToManyField('Interests')

    ...

   def save(self, *args, **kwargs):
       super().save(*args, **kwargs)

...

def userprofile_receiver(sender, instance, created, *args, **kwargs):
    if created:
        userprofile = UserProfile.objects.create(user=instance)
    else:
        instance.userprofile.save()

post_save.connect(userprofile_receiver, sender=settings.AUTH_USER_MODEL)



 #forms.py

 class SignupForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(SignupForm, self).__init__(*args, **kwargs)
        self.fields['first_name'].widget = forms.TextInput(attrs={'placeholder': 'Enter first name'})
        self.fields['last_name'].widget = forms.TextInput(attrs={'placeholder': 'Enter last name'})

    first_name = forms.CharField(max_length=100)
    last_name = forms.CharField(max_length=100)

    interests  = forms.ModelMultipleChoiceField(widget=forms.CheckboxSelectMultiple, help_text="Choose your interests", queryset=Interests.objects.all())

    image = forms.ImageField(help_text="Upload profile image ")
    fields = forms.ChoiceField(help_text="Choose your fields ")
    category = forms.ChoiceField(help_text="Choose your category")

    class Meta:
        model = UserProfile
        fields = ('first_name', 'last_name',  'name', 'image', 'fields', 'category', 'description', 'phone', 'facebook', 'twitter', 'skype', 'site', 'address', 'interests' ,'biography')
        widgets = {
             ...
            'description': forms.TextInput(attrs={'placeholder': 'Your description'}),
            'address': forms.TextInput(attrs={'placeholder': 'Enter address'}),
            'biography': forms.TextInput(attrs={'placeholder': 'Enter biography'}),
            ....
    }
    def signup(self, request, user):
        # Save your user
        user.first_name = self.cleaned_data['first_name']
        user.last_name = self.cleaned_data['last_name']
        user.save()

        user.userprofile.image = self.cleaned_data.get('image')
        user.userprofile.fields = self.cleaned_data['fields']
        user.userprofile.category = self.cleaned_data['category']
        user.userprofile.description = self.cleaned_data['description']
        interests = self.cleaned_data['interests']
        user.userprofile.interests.set(interests)
        user.userprofile.save()


# settings.py or base.py

ACCOUNT_SIGNUP_FORM_CLASS = 'nameApp.forms.SignupForm'

그게 다야. (: