django 04. 장고 개인 프로젝트 6 - 회원가입, 로그인 폼 꾸미기

|

개인 프로젝트에 회워가입, 로그인 페이지를 커스터마이징 하는 과정을 기록하였습니다.

원하는 상태

  • 회원가입, 로그인 폼을 css를 통해서 커스터마이징한다.
  • User model form 필드의 기본 글자 수 제한을 변경한다.

결과물

회원가입 폼 커스터마이즈

forms.py 수정

  • 회원가입에서 사용되는 UserForm을 수정한다.
  • widgets 를 통해서 각 폼 필드의 형식과 class명을 포함한 어트리뷰트를 추가할 수 있다.
  • labels 를 통해서 각 폼 필드의 label을 지정할 수 있다.
  • __init__ 메소드를 통해서 부모모델 User의 기본 설정을 (maxlength 등) 변경할 수 있다.
from django import forms
from django.contrib.auth.models import User

class UserForm(forms.ModelForm):
    class Meta:
        model = User
        fields = ['username', 'email', 'password']
        widgets = {
            'username': forms.TextInput(attrs={'class': 'form-control', 'placeholder':'15자 이내로 입력 가능합니다.'}),
            'email': forms.EmailInput(attrs={'class': 'form-control'}),
            'password' : forms.PasswordInput(attrs={'class': 'form-control'}),
        }
        labels = {
            'username': '닉네임',
            'email': '이메일',
            'password': '패스워드'
        }
    # 글자수 제한
    def __init__(self, *args, **kwargs):
        super(UserForm, self).__init__( *args, **kwargs)
        self.fields['username'].widget.attrs['maxlength'] = 15

views.py

def signup(request):
    if request.method == "POST":
        form = UserForm(request.POST)
        if form.is_valid():
            new_user = User.objects.create_user(**form.cleaned_data)
            login(request, new_user)
            return redirect('index')
        else:
            return HttpResponse('사용자명이 이미 존재합니다.')
    else:
        form = UserForm()
        return render(request, 'memo_app/adduser.html', {'form': form})

adduser.html 템플릿 수정


{% if user.is_authenticated %}
<script type="text/javascript">
  alert('잘못된 접근입니다. \n회원가입을 위해서는 로그아웃이 필요합니다.')
  window.location.href = '/';
</script>
{% else %}
<form method="POST" action="" class="sign-up-form">
  {%csrf_token%}
  <h2 class="sub-title"> 회원가입 </h2>
  {% for field in form %}
      <div class="form-group">
        {{ field.label }}
        {{field}}
      </div>
  {% endfor %}
  <button type="submit" class="save btn btn-success">회원가입</button>
  <a href="{% url 'index' %}">
    <button type="button" class="btn btn-danger">취소</button>
  </a>
</form>

로그인 폼 커스터마이즈

urls.py 수정

  • django 내장 인증기능 auth_views.login 을 사용하면, 기본 템플릿의 경로는 templates/registration/login.html 이다
  • 별도의 템플릿을 사용하고자 하는 경우 아래와 같은 별도 설정이 필요하다.
from django.contrib.auth import views as auth_views

urlpatterns = [
  url(r'^login/$', auth_views.login,  {'template_name':'memo_app/login.html'}),
]

login.html 템플릿 수정

  • 템플릿 수정을 통해서 원하는 class, id 등의 어트리뷰트 설정이 가능하다.

<form method="post" action="{% url 'login' %}" class="sign-in-form">
  {%csrf_token%}
  <h2 class="sub-title"> 로그인 </h2>
  {% if form.errors %}
  <p>Your username and password didn't match. Please try again.</p>
  {% endif %}
  {% if next %}
      {% if user.is_authenticated %}
      <p>Your account doesn't have access to this page. To proceed,
      please login with an account that has access.</p>
      {% else %}
      <p>Please login to see this page.</p>
      {% endif %}
  {% endif %}
  <div class="form-group">
    <label for="{{ form.username.id_for_label }}">닉네임</label>
    <input class="form-control" id="{{ form.username.id_for_label }}" maxlength="15" name="{{ form.username.html_name }}" type="text" />
  </div>
  <div class="form-group">
    <label for="{{ form.password.id_for_label }}">패스워드</label>
    <input class="form-control" id="{{ form.password.id_for_label }}" maxlength="120" name="{{ form.password.html_name }}" type="password" />
  </div>
  <input type="submit" class="save btn btn-success" value="로그인">
  <a href="{% url 'index' %}">
    <button type="button" class="btn btn-danger">취소</button>
  </a>
  <input type="hidden" name="next" value="{{ next }}" />
</form>

django 04. 장고 개인 프로젝트 5 - 정렬방식 변경하기 (좋아요, 최신, 내가쓴글)

|

개인 프로젝트에 여러가지 정렬 기준에 따라서 정렬방식을 변경하는 과정을 기록하였습니다.

  • 원하는 상태 : 최신순/좋아요/내가쓴글 순으로 정렬방식을 변경한다.

결과물

template 수정

  • 화면에 정렬 기준을 변경하기 위한 요소(셀렉트박스)를 추가한다.

<select id="sort-select" onchange="location = this.value;">
  <option class="sort-date" value="/">최신순</option>
  <option class="sort-likes" value="?sort=likes">좋아요순</option>
  {% if user.is_authenticated %}
  <option class="sort-mypost" value="?sort=mypost">내가쓴글</option>
  {% endif %}
</select>

views.py 수정

  • views.py 내용중 정렬이 필요한 index 화면 부분을 수정한다.
  • request.GET.get('sort','') 을 통해서 url 쿼리스트링 ?sort=like 의 값을 가져온다.
  • request.GET['sort']와 같은 방법을 통해서도 쿼리스트링 값을 가져올 수 있지만, 없는 경우 오류가 발생한다.
  • ManyToManyField인 likes 컬럼을 기준으로 하려면 annotate 메소드 사용이 필요하다.
  • 1번째 기준인 ‘좋아요 수’가 같은 경우는 2번째 기준으로 ‘작성일’을 기준으로 정렬한다.
  • 참고글 : (엑셀만큼 쉬운) Django Annotation/Aggregation
  • .objects.filter() 을 통해서 조건에 맞는 복수의 오브젝트를 가져올 수 있다. (.objects.get() 에서는 오류 발생)
def index(request):
    sort = request.GET.get('sort','') #url의 쿼리스트링을 가져온다. 없는 경우 공백을 리턴한다

    if sort == 'likes':
        memos = Memos.objects.annotate(like_count=Count('likes')).order_by('-like_count', '-update_date')
        return render(request, 'memo_app/index.html', {'memos' : memos})
    elif sort == 'mypost':
        user = request.user
        memos = Memos.objects.filter(name_id = user).order_by('-update_date') #복수를 가져올수 있음
        return render(request, 'memo_app/index.html', {'memos' : memos})
    else:
        memos = Memos.objects.order_by('-update_date')
        return render(request, 'memo_app/index.html', {'memos' : memos})

참고 - 셀렉트박스 유지를 위한 스크립트

// get url query string
var getUrlParameter = function getUrlParameter(sParam) {
    var sPageURL = decodeURIComponent(window.location.search.substring(1)),
        sURLVariables = sPageURL.split('&'),
        sParameterName,
        i;

    for (i = 0; i < sURLVariables.length; i++) {
        sParameterName = sURLVariables[i].split('=');

        if (sParameterName[0] === sParam) {
            return sParameterName[1] === undefined ? true : sParameterName[1];
        }
    }
};
// 정렬방식 셀렉트 박스 유지
$(document).ready(function(){
  var sort = getUrlParameter('sort');
  if(sort == 'likes'){
    $('.sort-likes').prop('selected', 'selected')
  }else if(sort == 'mypost'){
    $('.sort-mypost').prop('selected', 'selected')
  }else{
    $('.sort-date').prop('selected', 'selected')
  }
});

django 04. 장고 개인 프로젝트 4 - 좋아요 버튼, ajax 통신

|

django 04. 장고 개인 프로젝트 (메모 앱) - 좋아요 버튼, ajax 통신

개인 프로젝트에 ajax 통신을 이용한 좋아요 기능을 추가하는 과정을 기록하였습니다.

  • 원하는 상태 : 마음에 드는 글에 대해서 좋아요를 누르면 누적된 좋아요 수가 표시된다. 좋아요 버튼는 글 하나당 한번만 누를 수 있다.

결과물

Memos 모델에 likes 컬럼 추가

  • 유저는 여러개의 메모에 좋아요를 할 수 있고, 메모는 여러 유저로부터 좋아요를 받을 수 있다.
  • 참고로 ForeignKey 는 글쓴이 컬럼에 적용 (유저는 어려개의 메모를 작성할 수 있고, 메모는 1사람의 유저(글쓴이)를 갖는다.)
  • 참고문서 : Many-to-many relationships
  • 참고문서 : property Decorator
  • 참고 문서 : related_name
  • models.py 수정
from django.contrib.auth.models import User

class Memos(models.Model):
  name_id = models.ForeignKey(User, on_delete = models.CASCADE)
  likes = models.ManyToManyField(User, related_name='likes')
  # User에서 접근할 때 related_name이 설정되지 않으면 User.memos_set.all()과 같은 방식으로 연관 모델에 접근한다.

  @property
  def total_likes(self):
    return self.likes.count() #likes 컬럼의 값의 갯수를 센다

View에 like 메소드 추가

try:
    from django.utils import simplejson as json
except ImportError:
    import json
from django.contrib.auth.models import User
from django.contrib.auth.decorators import login_required
from django.views.decorators.http import require_POST


@login_required
@require_POST
def like(request):
    if request.method == 'POST':
        user = request.user # 로그인한 유저를 가져온다.
        memo_id = request.POST.get('pk', None)
        memo = Memos.objects.get(pk = memo_id) #해당 메모 오브젝트를 가져온다.

        if memo.likes.filter(id = user.id).exists(): #이미 해당 유저가 likes컬럼에 존재하면
            memo.likes.remove(user) #likes 컬럼에서 해당 유저를 지운다.
            message = 'You disliked this'
        else:
            memo.likes.add(user)
            message = 'You liked this'

    context = {'likes_count' : memo.total_likes, 'message' : message}
    return HttpResponse(json.dumps(context), content_type='application/json')
    # dic 형식을 json 형식으로 바꾸어 전달한다.

url 패턴 추가

  • urls.py
urlpatterns = [
  url(r'^like/$', views.like, name='like'),
]

템플릿에 좋아요 버튼 및 ajax 코드 추가

  • default.html

<div class="thumbnail priority">
  <div class="caption">
    <h2>{{memo.title}}
      <span>&nbsp;&nbsp;by <span class= "writer_name">{{memo.name_id}}</span></span><br><span class="date">{{memo.update_date}}</span>
      <span class="control hidden" id = "control_id{{ forloop.counter0 }}">
        <a href="{% url 'modify_memo' memokey=memo.pk %}"><img src="{% static 'image/edit.png' %}" class= "edit" alt="수정"></a>
        <a href="{% url 'delete_memo' memokey=memo.pk %}" onclick="return confirm('정말 삭제하시겠습니까?')"><img src="{% static 'image/delete.png' %}" class="delete" alt="삭제"></a>
      </span>
      <input type="button" class="like" name="{{ memo.id }}" value="Like">
      <p id="count{{ memo.id }}">count : {{ memo.total_likes }}</p>
    </h2>
    <p>{{memo.text}}</p>
  </div>
</div>

  • ajax 통신 error 발생시 아래와 같은 코드를 통해서 문제 내용을 파악하기 쉬워진다.

<script type="text/javascript">
// 인증에 따른 수정, 삭제 버튼 숨김처리
  for(i = 0; i < $(".writer_name").length; i++){
    if($("#user_name").text() == $(".writer_name")[i].innerHTML){
      $("#control_id"+i).removeClass("hidden");
    }
  }

// 좋아요 버튼 처리
// 버튼 클릭 > ajax통신 (like url로 전달) > views의 like 메소드에서 리턴하는 값 전달받기 > 성공시 콜백 호출
$('.like').click(function(){
  var pk = $(this).attr('name') // 클릭한 요소의 attribute 중 name의 값을 가져온다.
  $.ajax({
      type: "POST", // 데이터를 전송하는 방법을 지정한다.
      url: "{% url 'like' %}", // 통신할 url을 지정한다.
      data: {'pk': pk, 'csrfmiddlewaretoken': '{{ csrf_token }}'}, // 서버로 데이터를 전송할 때 이 옵션을 사용한다.
      dataType: "json", // 서버측에서 전송한 데이터를 어떤 형식의 데이터로서 해석할 것인가를 지정한다. 없으면 알아서 판단한다.
      // 서버측에서 전송한 데이터 views.py like 메소드
      // context = {'likes_count' : memo.total_likes, 'message' : message}
      // json.dump(context)를 통해서 json 형식으로 전달된다.

      success: function(response){ // 성공했을 때 호출할 콜백을 지정한다.
        id = $(this).attr('name')
        $('#count'+ pk).html("count : "+ response.likes_count);
        alert(response.message);
        alert("좋아요수 :" + response.likes_count);
      },
      error:function(request,status,error){
        alert("code:"+request.status+"\n"+"message:"+request.responseText+"\n"+"error:"+error);
      }
  });
})
</script>

django 04. 장고 개인 프로젝트 3 - 자신의 글만 수정, 삭제 가능하도록 만들기

|

django 04. 장고 개인 프로젝트 (메모 앱) - 자신의 글만 수정, 삭제 가능하도록 만들기

인증에 따른 기능 제한을 추가하는 과정에서 고민한 부분과 배운 것을 기록합니다.

결과물


삭제, 수정 제한 - 내가 쓴 글만 수정, 삭제하기

  • 현재 상태 : 회원가입, 로그인, 로그아웃 기능을 추가했지만 누구나 글을 수정, 삭제할 수 있는 상태이다.
  • 원하는 상태 : 로그인한 사용자가 자신이 쓴 글만 수정, 삭제할 수 있도록 하고싶다.

어떻게 할 수 있을까? 1 (아이디어)

  • 삭제 버튼 숨김 / 표시
    • 로그인 전 : 모든 글에 수정, 삭제 버튼이 보이지 않는다.
    • 로그인 후 : 자신이 쓴 글에만 수정, 삭제 버튼이 보인다.
  • 수정, 삭제 시 사용자 확인
  • 수정, 삭제하려는 글의 글쓴이와, 로그인 되어있는 유저가 일치하는지 비교한다.

어떻게 할 수 있을까? 2 (구현방법)

삭제 버튼 숨김 / 표시

  • 로그인 전 : 모든 글에 수정, 삭제 버튼이 보이지 않는다.
    • .hidden 클래스의 추가/삭제 를 통해서 해당 태그 요소의 숨김/표시를 제어한다.
    • 수정, 삭제 버튼을 <span class="control hidden"> 태그로 둘러싸고 .hidden{display:none.}을 통해서 해당 요소를 숨김처리한다.
        
      <span class="control hidden">
        <a href="{% url 'modify_memo' memokey=memo.pk %}"><img src="{% static 'image/edit.png' %}" class= "edit" alt="수정"></a>
        <a href="{% url 'delete_memo' memokey=memo.pk %}" onclick="return confirm('정말 삭제하시겠습니까?')"><img src="{% static 'image/delete.png' %}" class="delete" alt="삭제"></a>
      </span>
        
    
  • 로그인 후 : 자신이 쓴 글에만 수정, 삭제 버튼이 보인다.
    • 로그인한 유저메모의 글쓴이를 비교하여 일치하는 경우만 수정, 삭제 버튼을 표시한다.(.hidden 클래스 삭제)
    • 로그인한 유저는 탬플릿 내에서 {user.username} 으로 표시할 수 있다.
    • 하지만, 자바스크립트에서는 {} 을 사용할 수 없다. 어쩌지?
    • {user.username}을 <span id="user_name"></span> 으로 둘러싸고 제이쿼리를 이용하여 해당 태그 안의 텍스트 값을 가져오자.
      
    // html
    <span id="user_name">{{ user.username }}</span>
    
    // javascript
    $("#user_name").text() // user_name id를 가진 태그 안의 텍스트 값 가져오기
      
    
    
    • 각 메모의 글쓴이는 탬플릿 내에서 for 문을 돌면서 {memo.name_id} 로 표시한다.
    • {memo.name_id}는 값이 여러개라서 ID를 쓸 수가 없네 어쩌지?
    • {memo.name_id}을 <span class="writer_name"></span> 으로 둘러싸고 제이쿼리를 이용하여 해당 태그 안의 텍스트를 리스트로 가져온다.
      
    // html
    <span class= "writer_name">{{memo.name_id}}</span>
    
    // javascript
    $(".writer_name") // .writer_name 클래스를 가진 태그 전체를 리스트로 출력
    $(".writer_name")[0].innerHTML  // .innerHTML로 태그 안의 텍스트 값 가져오기
      
    
    
    • for 문으로 반복을 돌면서, 로그인한 유저명 - user_name과 메모의 글쓴이 - writer_name이 일치한다면, 반복 순서 i에 해당하는 메모의 수정,삭제 버튼 블럭 태그를 선택하여 클래스값 hidden을 지워준다.
      • 수정,삭제 버튼 블럭 태그에 {forloop.counter} 를 통해서 특정 숫자를 포함한 아이디를 추가한다.
      • forloop.counter : 템플릿 내에서 for문으로 반복시 1씩 증가하는 숫자를 생성 가이드문서 (forloop.counter0 : 0부터 숫자를 생성)
      
    <!-- html -->
    <span class="control hidden" id = "control_id{{ forloop.counter0 }}">
      <a href="{% url 'modify_memo' memokey=memo.pk %}"><img src="{% static 'image/edit.png' %}" class= "edit" alt="수정"></a>
      <a href="{% url 'delete_memo' memokey=memo.pk %}" onclick="return confirm('정말 삭제하시겠습니까?')"><img src="{% static 'image/delete.png' %}" class="delete" alt="삭제"></a>
    </span>
      
    
    // javascript
    for(i = 0; i < $(".writer_name").length; i++){
      if($("#user_name").text() == $(".writer_name")[i].innerHTML){
        $("#control_id"+i).removeClass("hidden");
      }
    }
    

수정, 삭제 시 사용자 확인

  • 문제가 생겼다. 개발자 도구로 hidden 클래스를 지워주면 남의 글도 삭제, 수정할 수 있다. 어떻게 하지?
  • 수정, 삭제시 로그인 되어있는 유저와 해당 글의 글쓴이가 일치하는지 비교한다.
  • 삭제 : views.py 의 delete 메소드 수정
def delete(request, memokey):
    memo = Memos.objects.get(pk = memokey)
    if memo.name_id == User.objects.get(username = request.user.get_username()):
        memo.delete()
        return redirect('index')
    else:
        return render(request, 'memo_app/warning.html')
  • 수정 : views.py 의 modify 메소드 수정
def modify(request, memokey):
    if request.method == "POST":
        #수정 저장
        memo = Memos.objects.get(pk = memokey)
        form = PostForm(request.POST, instance=memo)
        if form.is_valid():
             form.save()
             return redirect('index')
    else:
        #수정 입력
        memo = Memos.objects.get(pk = memokey)
        if memo.name_id == User.objects.get(username = request.user.get_username()):
            memo = Memos.objects.get(pk = memokey)
            form = PostForm(instance = memo)
            return render(request, 'memo_app/modify.html', {'memo' : memo, 'form' : form})
        else:
            return render(request, 'memo_app/warning.html')

django 04. 장고 개인 프로젝트 2 - 인증 (회원가입, 로그인)

|

django 04. 장고 개인 프로젝트 (메모 앱) - 인증 (회원가입, 로그인)

개인 프로젝트에 인증 기능을 추가하는 과정을 기록하였습니다.

결과물


회원가입

ModelForm 작성

  • 회원가입시 데이터를 입력 받을 폼을 작성한다.
  • ModelForm 은 자동적으로 당신이 제공한 model 소속의 폼을 작성한다. 그리고 필드에 기초해서 입력값을 확인한다.
  • forms.py
from django import forms
from django.contrib.auth.models import User

class UserForm(forms.ModelForm):
    class Meta:
        model = User
        fields = ['username', 'email', 'password']

url 패턴추가

  • urls.py
urlpatterns = [
    url(r'^join/$', views.signup, name='join'),
]

view 작성

  • views.py 에 signup 메소드 추가
  • POST request 인 경우, UserForm으로 받은 POST 값을 가지고 신규 유저를 등록
  • 일반 접속인 경우, UserForm 을 반환
  • views.py
from django.shortcuts import render, redirect
from .forms import UserForm
from django.contrib.auth.models import User
from django.contrib.auth import login

def signup(request):
    if request.method == "POST":
        form = UserForm(request.POST)
        if form.is_valid():
            new_user = User.objects.create_user(**form.cleaned_data)
            login(request, new_user)
            return redirect('index')
    else:
        form = UserForm()
        return render(request, 'memo_app/adduser.html', {'form': form})

template 작성


<h2>회원가입</h2>
<form method="post" action="">
    {% csrf_token %}
    {{ form.as_p }}
    <input type="submit" value="회원가입" />
</form>

views
adduser.html 탬플릿 구현화면

로그인 구현 첫번째 방법 - ModelForm 사용

ModelForm 작성

  • 로그인시 데이터를 입력 받을 폼을 작성한다.
  • ModelForm 은 자동적으로 당신이 제공한 model 소속의 폼을 작성한다. 그리고 필드에 기초해서 입력값을 확인한다.
  • forms.py
from django import forms
from django.contrib.auth.models import User

class LoginForm(forms.ModelForm):
    class Meta:
        model = User
        fields = ['username', 'password'] # 로그인 시에는 유저이름과 비밀번호만 입력 받는다.

url 패턴추가

  • urls.py
urlpatterns = [
  url(r'^login/$', views.signin, name='login'),
]

view 작성

  • views.py 에 signin 메소드 추가 (메소드 명이 함수명 ex. login() 등과 겹치지 않도록 주의)
  • POST request 인 경우, LoginForm으로 받은 POST 값을 가지고 인증 및 로그인
  • 일반 접속인 경우, LoginForm을 반환
  • views.py
from django.shortcuts import render, redirect
from django.http import HttpResponse
from .forms import UserForm, LoginForm
from django.contrib.auth.models import User
from django.contrib.auth import login, authenticate
from django.template import RequestContext

def signin(request):
    if request.method == "POST":
        form = LoginForm(request.POST)
        username = request.POST['username']
        password = request.POST['password']
        user = authenticate(username = username, password = password)
        if user is not None:
            login(request, user)
            return redirect('index')
        else:
            return HttpResponse('로그인 실패. 다시 시도 해보세요.')
    else:
        form = LoginForm()
        return render(request, 'memo_app/login.html', {'form': form})

template 작성

  • login.html

<h2>로그인</h2>
<form method="post" action="">
    {% csrf_token %}
    {{ form.as_p }}
    <input type="submit" value="로그인" />
</form>

views
login.html 탬플릿 구현화면

로그인 후 username을 탬플릿에서 표시

##

{% if user.is_authenticated %} <p>Welcome, {{ user.username }}. Thanks for logging in.</p> {% else %} <p>Welcome, new user. Please log in.</p> {% endif %}


-----

# 로그인 구현 두번째 방법 - Authentication Views 사용
> 장고는 login, logout, password management 를 위한 몇가지 views를 제공하고 있다.

## Authentication Views 도입 - url include
- urls.py

```python
urlpatterns = [
    url('^', include('django.contrib.auth.urls')),
]
  • 위의 include를 통해서 아래의 url 패턴을 사용할 수 있다.

^login/$ [name='login']
^logout/$ [name='logout']
^password_change/$ [name='password_change']
^password_change/done/$ [name='password_change_done']
^password_reset/$ [name='password_reset']
^password_reset/done/$ [name='password_reset_done']
^reset/done/$ [name='password_reset_complete']

상기의 url이 본인이 작성한 view를 사용하게 하는 방법

  • auth_views 사용
from django.contrib.auth import views as auth_views

urlpatterns = [
    url('^change-password/$', auth_views.password_change),
]
  • auth_views는 view의 상태를 변경할 수 있는 옵션 인자를 받는다. 예를 들어, 만약 template name을 변경하고 싶은 경우 인자 template name을 제공할 수 있다.
  • 그밖에 제공 가능한 인자는 가이드문서 에서 확인
urlpatterns = [
    url(r'^logout/$', auth_views.logout, {'next_page' : '/'}), #로그아웃 후 홈으로 이동
    url(r'^login/$', auth_views.login),
    url('^', include('django.contrib.auth.urls')),
]

로그인 후 홈으로 이동하도록 하는 방법

  • django.contrib.auth.views.login은 로그인이 성공하면 settings.LOGIN_REDIRECT_URL (which defaults to /accounts/profile/) 으로 리다이렉트 하도록 설정되어 있다.
  • 변경을 위해서는 settings.py 에 LOGIN_REDIRECT_URL 항목 추가가 필요하다.

  • settings.py
# 로그인 이후 경로 수정
LOGIN_REDIRECT_URL = "/"

글쓰기 PostForm 과 로그인한 usrname을 연결하는 방법 1

  • 글 작성후 POST로 데이터 전송시, 해당 모델 클래스의 name 컬럼에 현재 usrname 을 저장한다.
  • memo.name = request.user.get_username()
  • views.py
def post(request):
    if request.method == "POST":
        #저장
        form = PostForm(request.POST)
        if form.is_valid():
            memo = form.save(commit = False)
            memo.name = request.user.get_username()
            memo.generate()
            return redirect('index')
    else:
        #입력
        form = PostForm()
        return render(request, 'memo_app/form.html',{'form': form})

글쓰기 PostForm 과 로그인한 usrname을 연결하는 방법 2 - ForeignKey 사용

  • models.py 수정
  • Memos 모델 클래스의 컬럼 name_id 를 User 모델 클래스와 연결한다. ```python from django.db import models from django.utils import timezone from django.contrib.auth.models import User

Create your models here.

class Memos(models.Model): name_id = models.ForeignKey(User, on_delete = models.CASCADE)

def __str__(self):
return '%s by %s' % (self.title, self.name_id) ```
  • views.py 수정
  • memo.name_id = User.objects.get(username = request.user.get_username()) 를 통해서 현재 로그인된 username을 갖는 User의 오브젝트를 name_id 컬럼에 할당한다.
    def post(request):
      if request.method == "POST":
          #저장
          form = PostForm(request.POST)
          if form.is_valid():
              memo = form.save(commit = False)
              memo.name_id = User.objects.get(username = request.user.get_username())
              memo.generate()
              return redirect('index')