회원 가입

Kyuwon Cho·2021년 10월 29일
0

Project Recall

목록 보기
1/5

Model 작성

  1. 데이터베이스에 적절한 테이블을 만들기 위해 app내의 models.py에 model을 작성한다.
from django.db import models
from django.contrib.auth.models import AbstractUser

class CustomUser(AbstractUser):
    email = models.EmailField()
    self_prove = models.CharField(max_length=50)
    self_prove_answer = models.CharField(max_length=50)

    def __str__(self):
        return self.username
  1. AbstractUser와 AbstractBaseUser는 장고에서 제공하는 User model이다. 둘의 차이점은 AbstractUser는 User model이 제공하는 field를 사용하면서 새로운 fields, function을 추가를 시킬 수 있는 것이고 AbstractBaseUser는 처음부터 끝까지 작성해야되는 empty model이라고 생각하면 된다.

    AbstractBaseUser에서 상속 가능한 요소

    • id: primay key(값은 unique하다)
    • password
    • last_login

    AbstractUser에서는 기본적으로 AbstractBaseUser 외 추가적인 요소를 상속할 수 있다.

    • fields
      • username: 계정
      • first_name: 이름
      • last_name: 성
      • email: 이메일
      • is_staff: 직원여부(authority를 주기 위해 구분)
      • is_active: 계정 활성화 여부
      • date_joined: 가입일
    • functions
      • def clean(self): 이메일을 소문자화 시켜주는 함수(이메일은 소문자만 사용가능하다)
      • def get_full_name(self) 유저의 fullname을 가져오는 함수(first와 last name을 조합)
      • def get_short_name(self) first_name과 같이 이름을 지정하는 것인데 identifier로 쓸 수 있다(informal identifier)
      • def email_user(self, subject, message, from_email=None, **kwargs):
  2. 해당 프로젝트에서는 AbstractUser model을 기본으로 사용하고 필요한 데이터(email, 본인확인질문, 답)를 추가하는 것으로 결정했다.

  3. AbstractUser를 상속받았을 경우, settings.py에 아래 코드를 추가해줘야 한다.

AUTH_USER_MODEL = 'appname.modelName'

Form 작성

  1. 회원가입 시스템을 만들때 필요한 form을 app폴더에 form.py를 만들어서 작성한다

  2. 장고에는 기본적으로 제공하는 회원가입 form인 UserCreationForm이 존재한다.

    • UserCreationForm에 포함되는 fields
      • username

      • password1

      • password2

        validate_password()를 통해 password 적합성을 체크한다

        set_password()를 통해 적합한 password를 설정한다.

  3. 기본 form을 유지하고 추가적으로 field를 더하기 위해 UserForm을 새로 만들어 줄 수 있다. Form을 통해 유저들이 html에 데이터를 입력할 수 있게 된다.

    class UserForm(UserCreationForm):
        last_name = forms.CharField(label="성")
        first_name = forms.CharField(label="이름")
        email = forms.EmailField(label="이메일")
        self_prove = forms.CharField(label='본인인증 질문')
        self_prove_answer = forms.CharField(label='본인인증 질문 정답')
    
        class Meta:
            model = CustomUser
            fields = (
                "username",
                "last_name",
                "first_name",
                "password1",
                "password2",
                "email",
                "self_prove",
                "self_prove_answer"
            )
    
        def save(self):
            user = super(UserForm, self).save(commit=False)
            user.save()
            try:
                student = Group.objects.get(name='student')
                student.user_set.add(user)
            except Group.DoesNotExist:
                student = Group.objects.create(name='student')
                student.user_set.add(user)
            return

    class Meta에는 fields 외의 것을 수정, 작성할 때 사용되는 class이다.

    • class Meta
      • model=CustomUser 해당 form이 어떤 모델을 위해 작성되는지 정하는 코드이다. CustomUser라는 모델을 위한 form이라는 것을 명시한다.
      • fields = ("username", "last_name".....) 원래 form의 fields인 "username", "password1", "password2" 외에 추가할 필드를 명시해준다.
    • def save(self) form이 save될 때 실행 될 코드다. 이번 프로젝트에서는 form이 save될 때 그룹을 선별하기 위해 작성 된 코드다. (위 코드는 student라는 그룹을 만들어서 user를 넣거나 이미 그룹이 존재하면 넣기만 한다.)
  4. Form 작성 이후에는 해당 form과 UserManager작성이 가능하나 장고에서 기본적으로 제공하는 것이 충분하여서 따로 커스터마이징을 하지 않았다.

View 작성

  • 장고(Django)에서 views는 controller의 역할을 맞는다.
  • 회원가입시 Instruction Code 입력 여부에 따라 유저들의 staff여부와 학생 또는 강사로 나누어서 그룹을 지정해주었다. staff여부만으로 권한 설정이 가능하지만, admin이 관리하기 용이하게 그룹을 지정해주었다. (instructor만 staff가 아니게 될 수 있기 때문)
def signup(request):
    if request.method == 'POST':  # request 들어온 것이 post방식이면
        if request.POST['teacher_code'] in ['A0001', 'A0002']:
            form = StaffForm(request.POST)
        else:
            form = UserForm(request.POST)  # form에 UserForm post version으로 저장한다
        if form.is_valid():  # form이 valid하면
            form.save()
            return redirect('../login')
    else:
        form = UserForm()  # 계정 생성 화면 리턴
    return render(request, './common/signup.html', {'form': form})
  • request요청이 POST이냐 GET이냐에 따라 수행되는게 다르다. GET으로 들어오면 signup.html에 Form에서 커스터마이징한 UserForm을 넘겨주면서 해당 html을 열어준다.

HTML 작성

<div class="container my-3">
    <div class="row my-3">
        <div class="col-4">
            <h4>계정생성</h4>
        </div>
    </div>
    <form method="post" class="post-form" action="{% url 'common:signup' %}">
        {% csrf_token %}
        <div class="form-group">
            <label for="username">아이디</label>
            <input type="text" class="form-control" name="username" id="username"
                   value="{{ form.username.value|default_if_none:'' }}">
        </div>

        <div class="form-group">
            <label for="password1">비밀번호</label>
            <input type="password" class="form-control" name="password1" id="password1"
                   value="{{ form.password1.value|default_if_none:'' }}">
        </div>
        <div class="form-group">
            <label for="password2">비밀번호 재확인</label>
            <input type="password" class="form-control" name="password2" id="password2"
                   value="{{ form.password2.value|default_if_none:'' }}">
        </div>
        <div class="form-group">
            <label for="last_name">성(Last Name)</label>
            <input type="text" class="form-control" name="last_name" id="last_name"
                   value="{{ form.last_name.value|default_if_none:'' }}"> <div class="form-group">
        </div>
            <label for="first_name">이름(First Name)</label>
            <input type="text" class="form-control" name="first_name" id="first_name"
                   value="{{ form.first_name.value|default_if_none:'' }}">
        </div>

        <div class="form-group">
            <label for="email">이메일</label>
            <input type="text" class="form-control" name="email" id="email"
                   value="{{ form.email.value|default_if_none:'' }}">
        </div>
        <div class="form-group">
            <label for="teacher_code">강사코드</label>
        <input type="text" name="teacher_code" id="teacher_code" value="강사님만 입력">
        </div>
        <input type="submit" value="가입하기">
        <input type="button" onclick="location.href='{% url 'common:login' %}'" value="login화면으로">
    </form>
</div>

위의 코드는 로그인 Form을 HTML로 구현한 코드이다. 이를 꾸며주는 CSS는 보다 나은 설명을 위해 잠시 빼두었다.

<form id="registerForm" method="post" action="{% url 'common:signup' %}">
                {% csrf_token %}
                {% include "form_errors.html" %}

클라이언트와 서버는 서로 http프로토콜의 GET과 POST를 사용하여 데이터를 주고 받는다.

이때, 클라이언트가 서버로 데이터를 보낼 때 간편하게 사용 가능한 것이 Form이다. Form으로 사용자로부터 데이터를 수집하여 서버에 보내는 형식으로 사용된다.

위 코드의 의미는,

아래 구현된 코드로 이용자에게 정보를 받아 POST방식으로 common 앱의 signup이라는 이름이 주어진 URL에 보낸다는 의미이다.

<div class="form-group">
    <label for="username">아이디</label>
    <input type="text" class="form-control" name="username" id="username"
           value="{{ form.username.value|default_if_none:'' }}">
</div>
<input type="submit" value="가입하기">

해당 form에 필요한 input을 이용자가 작성 가능하게끔 구현한 코드이다. 해당 코드의 input데이터는 text형식으로 데이터를 받아와 username이라 명명하고 id를 주는 코드이다. 데이터 입력 완료 후, 가입하기 버튼을 누르면 form을 제출하게끔 되어 있다.

0개의 댓글