signup with custom user - pai-plznw4me/django-initializer GitHub Wiki

Django ํšŒ์›๊ฐ€์ž… ๊ธฐ๋Šฅ ๋ฐ ํšŒ์›์ •๋ณด ์—ด๋žŒ(Profile)

django ์„ค์น˜์‹œ ๊ธฐ๋ณธ ์•ฑ ๊ธฐ๋Šฅ์œผ๋กœ ์œ ์ € ๋ชจ๋ธ์„ ์ œ๊ณตํ•œ๋‹ค.ํ•˜์ง€๋งŒ ์œ ์ € ์ƒ์„ฑ ๊ธฐ๋Šฅ์€ ๊ด€๋ฆฌ์ž ์•ฑ์—์„œ ์ œ๊ณต๋œ๋‹ค. ํ•ด๋‹น ํŽ˜์ด์ง€์—์„œ๋Š” django ๊ธฐ๋ณธ ์œ ์ € ๋ชจ๋ธ์„ ํ™œ์šฉํ•ด ํšŒ์› ๊ฐ€์ž… ํŽ˜์ด์ง€๋ฅผ ๋งŒ๋“ค๊ณ  ๊ธฐ๋ณธ ์œ ์ € ๋ชจ๋ธ์„ ํ™•์žฅํ•˜์—ฌ ๊ธฐ์กด ์œ ์ € ๋ชจ๋ธ์— ์ƒˆ๋กœ์šด ํ•„๋“œ๋ฅผ ์ถ”๊ฐ€ ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•œ๋‹ค.

Signup with Custom user model

  • Model - Form - View- Template ํŒจํ„ด์œผ๋กœ ๊ฐœ๋ฐœ ๋จ.

Step 1. Model

  • User ๋ชจ๋ธ ์ƒ์†๋ฐ›์•„ ์ƒˆ๋กœ์šด field ์ถ”๊ฐ€ํ•˜๊ธฐ
from django.contrib.auth.models import AbstractUser
from django.db import models


# Create your models here.
class CustomUser(AbstractUser): # <-- ์ƒ์† ๋ถ€๋ถ„
    phone_number = models.CharField(max_length=11)  # ์ „ํ™”๋ฒˆํ˜ธ
    career = models.IntegerField()  # ๊ฒฝ๋ ฅ
    rank = models.CharField(max_length=10)  # ์ง๊ธ‰
    date_company_joined = models.DateField()  # ์ž…์‚ฌ ๊ธฐ๊ฐ„
    gender = models.CharField(max_length=3)  # ์„ฑ๋ณ„
    id_number = models.CharField(max_length=13)  # ์ฃผ๋ฏผ๋“ฑ๋ก๋ฒˆํ˜ธ
    department = models.CharField(max_length=13)  # ๋ถ€์„œ
    resume = models.FileField(blank=True, null=True)  # ์ด๋ ฅ์„œ
    id_photo = models.ImageField(blank=True, null=True, upload_to='')  # ์ฆ๋ช…์‚ฌ์ง„

    def __str__(self):
        return self.username

AbstractUser ์•„๋ž˜์™€ ๊ฐ™์€ field์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค. username, first_name, last_name, email, date_joined ,is_staff ๊ทธ๋Ÿฌ๋ฏ€๋กœ AbstractUser ์„ ์ƒ์†๋ฐ›๋Š” CustomUser ์—์„œ๋Š” ์œ„ AbstractUser ์—์„œ ์ •์˜๋œ field ์ด์™ธ์— ์ถ”๊ฐ€ํ•˜๊ณ  ์‹ถ์€ field ์„ ์ •์˜ํ•˜๋ฉด ๋œ๋‹ค

โš ๏ธ ์ƒˆ๋กญ๊ฒŒ ์ถ”๊ฐ€๋˜๋Š” ํ•„๋“œ์— null ํ—ˆ์šฉ์ด ์•ˆ๋˜๊ฑฐ๋‚˜ ํ•„๋“œ์— ๊ธฐ๋ณธ๊ฐ’์ด ์„ค์ •๋˜์ง€ ์•Š์œผ๋ฉด manage.py createsupseruser ์œผ๋กœ ์Šˆํผ์œ ์ €์ƒ์„ฑ์‹œ admin site ์— ์ ‘๊ทผ์ด ์•ˆ๋ ์ˆ˜ ์žˆ๋‹ค.

Step 2. ๊ธฐ์กด ์œ ์ € ์ƒˆ๋กœ์šด ModelForm ์ƒ์„ฑํ•˜๊ธฐ

class CustomUserCreationForm(UserCreationForm):
    class Meta:
        model = CustomUser
        fields = ('username',
                  'date_company_joined',
                  'phone_number',
                  'career',
                  'rank',
                  'date_company_joined',
                  'gender',
                  'id_number',
                  'department',
                  'resume',
                  'id_photo',
                  'password1',
                  'password2')  # <- User ์ƒ์„ฑ์‹œ ๋ณด์—ฌ์ค„ field ์„ ์ •์˜ํ•œ๋‹ค.

        profile_fields = ('username',
                          'date_company_joined',
                          'phone_number',
                          'career',
                          'rank',
                          'date_company_joined',
                          'gender',
                          'id_number',
                          'department',
                          'resume',
                          'id_photo')

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

        # null=True๋กœ ์„ค์ •ํ•œ ํ•„๋“œ์— ๋Œ€ํ•ด required๋ฅผ False๋กœ ์„ค์ •
        self.fields['resume'].required = False
        self.fields['id_photo'].required = False

UserCreationForm์˜ ์ƒ์† ๊ด€๊ณ„๋Š” ์•„๋ž˜์™€ ๊ฐ™๋‹ค. forms.ModelForm โ†’BaseUserCreationForm โ†’ UserCreationForm ModelForm ์ด ๋ถ€๋ชจ ํด๋ž˜์Šค์ด๋‹ค. ModelForm ์‚ฌ์šฉ ๋ฐฉ๋ฒ•๋Œ€๋กœ UserCreateForm ์„ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.

Step 3. Django ์—์„œ ๊ธฐ์กด User ์„ ๋ฐ”๋ผ๋ณด์ง€ ์•Š๊ณ  CustomUser ์„ ๊ธฐ๋ณธ User ๋กœ ๋ฐ”๋ผ๋ณด๊ฒŒ ํ•œ๋‹ค.

# settings.py
...
AUTH_USER_MODEL = 'accounts.CustomUser'
admin_result

Step 4. HTML

<!-- templates/registration/login.html -->
<h2>Signup</h2>
<form action="" method="post" enctype="multipart/form-data">
  {% csrf_token %}
  {{ form.as_p }}
  <button type="submit">Signup</button>
</form>

{{ errors }}

Step 5. View

def signup(request):
    if request.method == 'POST':
        form = CustomUserCreationForm(request.POST, request.FILES) # <-- FILES ์™€ ๊ฐ™์ด ์ž…๋ ฅ์ด ๋˜์–ด์•ผ ํ•œ๋‹ค.
        if form.is_valid():
            # file field ๋ฐ์ดํ„ฐ ์ €์žฅ
            inst = form.save(commit=False)

            # file field ๋ฐ์ดํ„ฐ ์ €์žฅ
            id_photo = form.cleaned_data['id_photo']
            inst.id_photo.save(id_photo.name, id_photo)

            # ์ผ๋ฐ˜ form data ์ €์žฅ
            inst.save()

            # login
            auth.login(request, inst)

            # profile ํŽ˜์ด์ง€๋กœ redirect ํ•จ
            return redirect('/account/profile')
        else:
            print('Errors:' , form.errors)
            return render(request, template_name='account/signup.html', context={'errors': form.errors})

    elif request.method == 'GET':
        form = CustomUserCreationForm() # <-๋ฐ”๋€ ๋ถ€๋ถ„
        return render(request, template_name='account/signup.html', context={'form': form})

    else:
        raise NotImplementedError

Step 6. Profile HTML

{% load index %}

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
  
{% for field in field_names %}
    {% with field_type=types|index:forloop.counter0 attr=user|getattribute:field %}
        {% if field_type == 'ImageField' %}
            {{ attr|getattribute:'url' }}
            <img src={{ attr|getattribute:'url' }}>
        {% else %}
            <p>{{ field }} : {{ attr }} : {{ types | index:forloop.counter0 }}</p>
        {% endif %}
    {% endwith %}
{% endfor %}

</body>
</html>

Step 7. Profile View

@csrf_exempt
def profile(request):
    user = CustomUser.objects.get(username=request.user)
    # field ์ด๋ฆ„์„ ์ถ”์ถœํ•ฉ๋‹ˆ๋‹ค.
    field_names = CustomUserCreationForm.Meta.profile_fields

    # field ์˜ type ์„ ์ถ”์ถœํ•ฉ๋‹ˆ๋‹ค.
    types = []
    for name in field_names:
        field = user._meta.get_field(name)
        # field ๊ฐ€ Image type ์ด๋ฉด 'ImageType' ์œผ๋กœ ํƒ€์ž…์„ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.
        # ๋ชจ๋ธ ํ•„๋“œ์˜ ๋‚ด๋ถ€ ํƒ€์ž…์€ ์‹ค์ œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ์‚ฌ์šฉ๋˜๋Š” ํƒ€์ž…์ž…๋‹ˆ๋‹ค.
        # get_internal_type()์œผ๋กœ ๋ฐ˜ํ™˜๋˜๋Š” ๊ฐ’์€ FileField ์ž…๋‹ˆ๋‹ค.
        if isinstance(field, models.ImageField):
            types.append('ImageField')
        else:
            types.append(field.get_internal_type())
    # template ์„ rendering ํ•ฉ๋‹ˆ๋‹ค.
    context = {'user': user, 'field_names': field_names, 'types':types}
    return render(request, template_name='account/profile.html', context=context)
โš ๏ธ **GitHub.com Fallback** โš ๏ธ