https://www.erdcloud.com/d/Nc5NE8DrLKLdCvQe4

'Django' 카테고리의 다른 글

스파르타 장고. 잘 못하는 것들.  (0) 2023.04.13
장고 정리: 5주  (0) 2023.04.12
파이썬 장고 실무 기초: 4  (0) 2023.04.05
파이썬 장고 실무 기초: 3  (0) 2023.04.05
파이썬 장고 실무 기초: 2  (0) 2023.04.04

4월 3일 - 연봉 1억 대기업 개발자 되는 법 특강을 들었다. 내가 느낀 바로는 공부를 잘하는 사람이 코딩을 잘한다 라는 뜻으로 느껴졌다. 예전에 완벽한 공부법 이라는 책을 읽으면서 메타인지에 대해 이미 알고 있었다. 그 얘기가 주 내용이었다.

하지만 조직의 메타인지도 있다는 것은 새로웠다. 이것은 조직이 무엇을 하고 무엇이 필요한지 알고 있는 것을 말한다.

 

4월 4일 - 알고리즘도 풀고 장고 실무도 했구나. 알고리즘은 정말 재밌다. 막막했지만 수학 할 때 처럼 일단 잘 모르겠으면 답을 보고 이해하고 다음 문제 풀면서 쉬운 문제들을 풀었다. 실력이 좀 쌓이고 어려운 문제를 풀 때 오랜 시간 고민하는 것이 의미가 있다. 수학처럼. 그리고 장고! 쉬운 듯 어려운 장고! 2주차까지 들었구나! 1주차는 파이썬 기초 하고 2주차 부터 본 강의 내용인데 그저 강의를 따라했기 때문일까 뭘 했는지 기억이 나질 않는다.

 

4월 5일 -  장고 4주차까지 했네! 그리고 개인과제  발제. 엄청 어려웠다. 그저 막막했다.

 

4월 6일 - 이때 부터 멘붕이 왔다...

 

4월 7일 - 장고를 하고 있는지 강의를 따라하는건지 전혀 모르는 상황이 되었다....

 

문제점은 주말에 여자친구를 만나고 깨달았다. 부트캠프를 하면서 여자친구와 2주만에 만났다. 정말 보고 싶었다.

여자친구는 우리의 미래를 위해 '현실'에 살면서 노력하고 있었다.

나는 '현실'에 살았었나? 집에서 그저 강의와 커리큘럼에 따라가기 바빴다.

하지만 생각해보니 내가 장고나 파이썬으로 프로그래밍을 잘한다면 커리큘럼도 잘 따라갈 것이라 생각이 들었다.

그저 강의를 보면서 따라하는게 아닌 '현실'의 프로그래밍을 위해 노력해야 한다는걸 깨달았다.

과감히 개인 과제는 포기하기로 했다. 그리고 점프 투 장고를 보면서 장고의 이해도를 높이기로 생각을 했다.

우리의 미래를 위해 시간을 쪼개고 쪼개서 밀도있게 이용하기로 마음먹었다.

매핑(mapping)이란 하나의 값을 다른 값으로 대응

패키지

장고 프로젝트를 만들면 루트 패키지가 되어지고,

프로젝트 내에 만드는 앱들은 서브 패키지가 된다.

 

장고의 MVT패턴

url을 만든다.

함수로

view와 연결해서 어떤 서비스를 해줄지 작성한다.

데이터를 저장해야 한다면 Model을 작성해서 틀을 정한다.

그리고 DB에 저장하고 클라이언트에게 화면을 보여준다.

from django.contrib

이런 식으로 사용하는 것들은 모두 앱이다. setting에 적어서 사용해야한다.

그리고 manage.py migrate로 알려줘야한다.

 

django-admin startapp <이름>

장고에 app을 만들 수 있다. 그리고 당연히 setting에 적어줘야한다.

쿼리셋(QuerySet)

쿼리셋(QuerySet)은 전달받은 모델의 객체 목록입니다. 쿼리셋은 데이터베이스로부터 데이터를 읽고, 필터를 걸거나 정렬을 할 수 있습니다.
= 아 뭔지 알겠다. 모델의 class대로 만들어진 데이터들을 말하는 거구나.

 

개인과제 오류!

product.html에서 action을 알아 듣게 해야함.

action은 url을 알아먹는다. 나는 product를 불러올 url을 공백으로 뒀다. 그래야 메인화면에 불러오니까...
하지만 home이라는 함수를 만들어서 만약 로그인 했다면 product url을 불러오고 아니라면 signup url을 불러오도록
수정을 해서 해결을 했다.! 가보자고!!

 

사이즈를 알아먹게 해야하는데왜 select에서못알아먹는거지?... value도 줬는데...
일단! 넘어가고! 입출고 구현을 해보자!
 
입출고 모델링을 해보자.
입고면 수량에 +를 해야하고,
출고면 수량에 -를 해줘야함.
.........
옼케 이해했어.
똑같이 모델을 만들고 출고면 전체 수량에 -만 해주면 됌.
해보자!
 
나는 그저... 강의 자료를 복붙하고 입맛에 맞춰 고쳐 쓰고 있을 뿐이야....
너는 전혀 스윙을 하고 있지 않아.
교수님의 말이 떠오르는 군...
git 특강 듣고, 점심 먹고, 과제 쪼금 하다가 저녁 먹고 7시에 강당가고.. 지금이다.
도데체  장고 강의에서 내가 배운 것은 뭐지?.. 강의가 그냥 막막하기만 하다.
주변 팀원 몇몇은 이미 끝낸 분도 계신다.
포기할까 생각이 든다.
공부 방법이 잘 못 된걸까?
열심히 노력했나 물어보면 맞다고 말 못할 것 같다.
무작정 열심히 하는 것도 도움이 안될것 같고..
짜증과 속상함과 막막함이 밀려온다. 복잡하고 바보 같다.
 
git diff : wd와 repo를 비교
git diff --staged : 스테이지와 repo 비교
git diff <1커밋> <2커밋> : 커밋끼리 비교.
1커밋에 비해서 2커밋은 뭐가 달라? 라고 물어보는 것.
 
git log --oneline , git log 차이는 한줄이냐 여러줄이냐 차이.
 
작업 되돌리기
revert : 버전을 되돌린 새로운 버전 만들기
안전하게/작업내역 남기고 싶을때 사용.
하지만 불필요한 중복된 커밋이 생김.
 
reset : 버전을 완전히 되돌리기
유의미한 커밋만 남기고 싶을때 .
soft : 리포에 커밋한 것만 되돌리는것.
mixed : 스테이지로 추가한 것을 되돌린다.
hard : 작업 디렉토리  변경사항도 되돌린다.
 
git stash(임시저장)

 

작업 내용을 임시 저장하고 최근 커밋으로 돌아간다.
git stash -, "메세지" : 메세지를 남길 수 있다.
git stash list
stash@{숫자}
숫자 == 최근에 임시저장 되었을 수록 0에 가깝다
git stash apply stash{0}
git stash drop @{0} - 임시저장 삭제

데이터 베이스 관계

one-to-many - 작성자 > 글들
one-to-one - 유저 > 프로필
many-to-many 피자 > 토핑
 

Many-To-Many 연습을 위한 앱 생성

앱생성
django-admin startapp restaurant
앱 연결
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'tweet',
    'user',
    'restaurant', #요기

Many-To-Many 모델 등록하기 (연습 - 피자/토핑)

모델 만들기
# restaurant/models.py
from django.db import models


# Create your models here.

class MyTopping(models.Model):
    class Meta:
        db_table = "my_topping"

    def __str__(self):
        return self.topping_name

    topping_name = models.CharField(max_length=100)


class MyPizza(models.Model):
    class Meta:
        db_table = "my_pizza"

    def __str__(self):
        return self.pizza_name

    pizza_name = models.CharField(max_length=100)
    pizza_topping = models.ManyToManyField(MyTopping)
터미널에 입력
python manage.py makemigrations
python manage.py migrate
어드민 페이지에 데이터베이스 모델 추가하기.
restaurant의 admin.py에 추가하기
from django.contrib import admin
from .models import MyTopping, MyPizza

# Register your models here.

admin.site.register(MyPizza)
admin.site.register(MyTopping)
user모델을 수정했기 때문에 접근 가능한 admin 계정이 없다.
계정 재생성.
python manage.py createsuperuser
 
관리자 페이지 가서 토핑 저장보면 에러가 난다!
장고가 createsuperuser를 잘 인식 못해서 그렇다고 한다.
db,migrations의 __init__.py 빼고 삭제!
다시 장고한테 알려주고 db에 반영하기.
python manage.py makemigrations
python manage.py migrate
db도 다시 연결해주고, 관리자도 재생성하면 에러 해결!

Django Shell로 Many-To-Many 모델 확인 해 보기

Django Shell : Django를 실행하지 않고도 기능들을 사용 할 수 있도록 도와주는 도구
터미널에 입력해서 실행!
python manage.py shell
피자에 있는 토핑 확인하기
>>> from restaurant.models import MyTopping, MyPizza

#전체 피자
>>> MyPizza.objects.all()
<QuerySet [<MyPizza: 도미노>, <MyPizza: 피자헛>, <MyPizza: 파파존스>]>

# 피자를 하나씩 불러볼게요
>>> MyPizza.objects.get(pizza_name='도미노')
<MyPizza: 도미노>
>>> MyPizza.objects.get(pizza_name='피자헛')
<MyPizza: 피자헛>
>>> MyPizza.objects.get(pizza_name='파파존스')
<MyPizza: 파파존스>

# 각 피자의 토핑들을 불러볼게요
>>> MyPizza.objects.get(pizza_name='도미노').pizza_topping.all()
<QuerySet [<MyTopping: 치즈>, <MyTopping: 치킨>]>
>>> MyPizza.objects.get(pizza_name='피자헛').pizza_topping.all()
<QuerySet [<MyTopping: 치즈>, <MyTopping: 페퍼로니>, <MyTopping: 올리브>]>
>>> MyPizza.objects.get(pizza_name='파파존스').pizza_topping.all()
<QuerySet [<MyTopping: 치즈>, <MyTopping: 페퍼로니>, <MyTopping: 피망>]>
토핑이 있는 피자 가져오기
>>> from restaurant.models import MyTopping, MyPizza

#전체 토핑
>>> MyTopping.objects.all()
<QuerySet [<MyTopping: 치즈>, <MyTopping: 페퍼로니>, <MyTopping: 올리브>, <MyTopping: 치킨>, <MyTopping: 피망>]>

#각 토핑별로 출력
>>> MyTopping.objects.get(topping_name='치즈')
<MyTopping: 치즈>
>>> MyTopping.objects.get(topping_name='페퍼로니')
<MyTopping: 페퍼로니>
>>> MyTopping.objects.get(topping_name='올리브')
<MyTopping: 올리브>
>>> MyTopping.objects.get(topping_name='치킨')
<MyTopping: 치킨>
>>> MyTopping.objects.get(topping_name='피망')
<MyTopping: 피망>

# 각 토핑이 들어있는 피자를 불러오기
>>> MyTopping.objects.get(topping_name='치즈').mypizza_set.all()
<QuerySet [<MyPizza: 도미노>, <MyPizza: 피자헛>, <MyPizza: 파파존스>]>
>>> MyTopping.objects.get(topping_name='페퍼로니').mypizza_set.all()
<QuerySet [<MyPizza: 피자헛>, <MyPizza: 파파존스>]>
>>> MyTopping.objects.get(topping_name='올리브').mypizza_set.all()
<QuerySet [<MyPizza: 피자헛>]>
>>> MyTopping.objects.get(topping_name='치킨').mypizza_set.all()
<QuerySet [<MyPizza: 도미노>]>
>>> MyTopping.objects.get(topping_name='피망').mypizza_set.all()
<QuerySet [<MyPizza: 파파존스>]>
Mnay-To-Many 모델은 '서로의 테이블에서' 서로의 데이터를 불러 올 수 있는 것이 특징
 

many-to-many 모델 만들어보기

사람 간의 모델이기 때문에 many-to-many 모델을 user 모델을 추가할 거다.
# user/models.py
from django.db import models
from django.contrib.auth.models import AbstractUser
from django.conf import settings

# Create your models here.
class UserModel(AbstractUser):

    class Meta:
        db_table = "my_user"

    bio = models.TextField(max_length=500, blank=True)
    follow = models.ManyToManyField(settings.AUTH_USER_MODEL,related_name='followee')
세팅 파일을 그대로 가져오는게 아니라 장고가 관리하는 세팅을 가져오는 이유는 나중에 세팅을 여러 파일로 나누어 적용하게 되는데 알아서 세팅파일을 가져오도록 하는 것.
 
이제 장고에게 또 알려줘야지.
python manage.py makemigrations
python manage.py migrate
그리고 계정을 여러 개 만들고 어드민에서 팔로우를 추가 하여 데이터를 만들어보자.
 

Many-To-Many 모델 사용하기 (실전-친구 리스트/팔로우)

친구 리스트를 보여주는 기능!
팔로우 당할 사람이 click_user다. 이 사람의 팔로워들을 전부 가져와서 내가 없다면 팔로우 버튼이 보이고, 있다면 팔로우 취소 버튼이 보이도록 할거다.
views에 기능을 추가해주고.
# user/views.py 

@login_required
def user_view(request):
    if request.method == 'GET':
        # 사용자를 불러오기, exclude와 request.user.username 를 사용해서 '로그인 한 사용자'를 제외하기
        user_list = UserModel.objects.all().exclude(username=request.user.username)
        return render(request, 'user/user_list.html', {'user_list': user_list})


@login_required
def user_follow(request, id):
    me = request.user
    click_user = UserModel.objects.get(id=id)
    if me in click_user.followee.all():
        click_user.followee.remove(request.user)
    else:
        click_user.followee.add(request.user)
    return redirect('/user')
urls에 url 연결을 해주자.
path('user/', views.user_view, name='user-list'), 
path('user/follow/<int:id>',views.user_follow, name='user-follow')
그리고 user.html을 만들어주자.
  • views.py에서 전달 해 주는 user_list에 담겨있는 사용자를 {% for %} 로 반복해서 출력
  • 로그인 한 사용자는 {{ user }} 으로 출력합니다. 위에서 {{ ul }} 로 출력 해 주는 사용자는, views.py의 user_view함수에서 전달 받은 사용자
  • 아래에 있는 '팔로우' 혹은 '팔로우 취소' 링크는 views.py에서 생성한 user_follow 함수와 이어져 있음.
→ user.follow.all()는 해당 사용자가 팔로우 하는 사람들을 불러옵니다.
→ user.followee.all()는 해당 사용자를 팔로우 하는 사람들을 불러옵니다.
그리고 상단 네비게이션에 친구 버튼에 하이퍼링크를 추가 해주자.

'Django' 카테고리의 다른 글

장고 정리: 5주  (0) 2023.04.12
무신사 ERD  (0) 2023.04.09
파이썬 장고 실무 기초: 3  (0) 2023.04.05
파이썬 장고 실무 기초: 2  (0) 2023.04.04
파이썬 장고 실무 기초: 1  (0) 2023.04.03

장고의 모델 vs 나의 모델

장고에는 담을 수 있는 내용이 많은 테이블을 기본적으로 많이 제공해준다.
나의 모델과 장고의 모델을 합쳐 사용하면 더 좋게 개발 할 수 있다.
 

User모델 업그레이드

장고에서 기본적으로 제공하는 모델을 사용하기 위한 방법.
from django.db import models 
from django.contrib.auth.models import AbstractUser # 이 줄 추가!


# Create your models here. 
class UserModel(AbstractUser): #상속시켜줘야함!

    class Meta: 
        db_table = "my_user" # 여기는 테이블 이름이에요! 꼭 기억 해 주세요!

    bio = models.TextField(max_length=500, blank=True) #필요한 테이블만 남기고 나머지는 삭제.
Django는 auth_user를 사용자 관리 테이블로 지정 해 놓았어요. 우리가 만든 모델로 이것을 바꾸려면 Django에게 알려주어야 합니다.
settings.py 맨 밑에 밑에 코드 추가.
AUTH_USER_MODEL = 'user.UserModel'
Django에게 기본 인증과정 (AUTH_USER_MODEL)을 user앱에 작성한 UserModel로 사용하겠다! 라고 알려주는 과정

user모델 적용시키기.

터미널에 입력!
python manage.py makemigrations  
python manage.py migrate

사용자 모델 적용시키기 - 회원가입 수정하기.

맨 위에 밑에 코드 추가하고.
# user/views.py 
from django.contrib.auth import get_user_model #사용자가 있는지 검사하는 함수
유저모델을 사용하도록 수정을해보자.
# user/views.py 
def sign_up_view(request): 
    if request.method == 'GET': 
        return render(request, 'user/signup.html') 
    elif request.method == 'POST': 
        username = request.POST.get('username', None) 
        password = request.POST.get('password', None) 
        password2 = request.POST.get('password2', None) 
        bio = request.POST.get('bio', None) 
        if password != password2: 
            return render(request, 'user/signup.html') 
        else: 
            exist_user = get_user_model().objects.filter(username=username) 
            if exist_user: 
		return render(request, 'user/signup.html') # 사용자가 존재하기 때문에 사용자를 저장하지 않고 회원가입 페이지를 다시 띄움 
            else: 
                UserModel.objects.create_user(username=username, password=password, bio=bio) #이렇게 한 줄로 바뀌었다. 
                return redirect('/sign-in') # 회원가입이 완료되었으므로 로그인 페이지로 이동
이렇게 하고  회원가입을 하고 데이터베이스를 확인해보면 비번이 암호화되서 알 수 없다. 장고의 기본 기능. 좋네!

사용자 모델 적용하기 - 로그인 수정하기.

user/views.py에 맨 위에 추가.
auth는 authentication( 유저 인증 )
contrib은 contributed ( 기여하다 )
# user/views.py 
from django.contrib import auth # 사용자 auth 기능

 

# user/views.py 
def sign_in_view(request): 
    if request.method == 'POST': 
        username = request.POST.get('username', None) 
        password = request.POST.get('password', None)

        me = auth.authenticate(request, username=username, password=password)  # 사용자 불러오기 
        if me is not None:  # 저장된 사용자의 패스워드와 입력받은 패스워드 비교 
            auth.login(request, me) 
            return HttpResponse("로그인 성공") 
        else: 
            return redirect('/sign-in')  # 로그인 실패 
    elif request.method == 'GET': 
        return render(request, 'user/signin.html')
from django.contrib import auth 를 사용하면 위처럼 비밀번호까지 체크를 해 주고, 로그인 기능까지 간단하게 해결이 가능.
 

로그인 이후 기능 다듬기 - 로그인 후 페이지 이동하기.

로그인 후 로그인이 되었다는 글만 띄어주고 있다. 글을 쓸 수 있는 페이지로 이동을 시키자.

html 만들기

tweet이라는 폴더를 templates에 만들고 home.html을 만든다.

home.html 연결하기.

views.
# tweet/views.py 
from django.shortcuts import render, redirect 
# Create your views here. 
def home(request): 
    user = request.user.is_authenticated  # 사용자가 인증을 받았는지 (로그인이 되어있는지) 
    if user: 
        return redirect('/tweet') 
    else: 
        return redirect('/sign-in') 
def tweet(request): 
    if request.method == 'GET': 
        return render(request, 'tweet/home.html')
user = request.user.is_authenticated → 장고가 제공하는 사용자 모델을 사용 했을 때 쓸 수 있는 함수인데요, '사용자가 로그인 했는지' 검사 해 주는 기능
urls.
urls.py를 만들고 코드를 추가한다.
# tweet/urls.py 
from django.urls import path 
from . import views 
urlpatterns = [ 
    path('', views.home, name='home'), # 127.0.0.1:8000 과 views.py 폴더의 home 함수 연결 
    path('tweet/', views.tweet, name='tweet') # 127.0.0.1:8000/tweet 과 views.py 폴더의 tweet 함수 연결 
]
장고에 알려주기
# mySpartaSns/urls.py 
from django.contrib import admin 
from django.urls import path, include 
urlpatterns = [ 
    path('admin/', admin.site.urls), 
    path('', include('user.urls')), 
    path('', include('tweet.urls')) 
]
로그인 시 글 출력을 home.html로 이동 하도록 수정.
#user/views.py 
def sign_in_view(request): 
    if request.method == 'POST': 
        username = request.POST.get('username', None) 
        password = request.POST.get('password', None) 
        me = auth.authenticate(request, username=username, password=password)  # 사용자 불러오기 
        if me is not None:  # 저장된 사용자의 패스워드와 입력받은 패스워드 비교 
            auth.login(request, me) 
            return redirect('/') # 여기 수정!!!!
        else: 
            return redirect('/sign-in')  # 로그인 실패 
    elif request.method == 'GET': 
        return render(request, 'user/signin.html')
 

로그인 이후 기능 다듬기

로그인 후에 부트스트랩에서 가져온 카드의 내용이 있으니 수정!!
<div class="col-md-3"> 
    <div class="card"> 
        <div class="card-body"> 
            <h5 class="card-title">{{ user.username }}</h5> 
            <p class="card-text"> {{ user.bio }}</p> 
        </div> 
    </div> 
</div>
로그인 후에도 로그인 하기와 회원가입 버튼이 있다. 수정!!
<!-- templates/base.html --> 
		... 생략  
				<li class="nav-item"> 
            <a class="nav-link" href="#"> 친구 <span class="sr-only"></span></a> 
        </li> 
    </ul> 
</div> 
<form class="form-inline my-2 my-lg-0"> 
    {% if not user.is_authenticated %} # 요줄 중요! 
        <ul class="navbar-nav mr-auto"> 
            <li class="nav-item active"> 
                <a class="nav-link" href="/sign-in"> Sign In <span class="sr-only"></span></a> 
            </li> 
            <li class="nav-item active"> 
                <a class="nav-link" href="/sign-up"> Sign Up <span class="sr-only"></span></a> 
            </li> 
        </ul> 
    {% else %} #요줄 중요! 
        {{ user.username }} 님 반갑습니다! 
    {% endif %} # 요줄은 if 문이 끝났다는 걸 알려주는 것 같다!
</form> 
... 생략
 

로그인 필요 기능과 로그아웃 만들기

로그인과 관련된 기능은 대표적으로 두 가지가 있습니다!
  1. 로그인 한 사람만 페이지에 접근 가능하게 만들기
  2. 로그인 한 사람은 사용 안 해도 되는 페이지
현재 로그인하면 로그인,회원가입 버튼이 보이고 들어 갈 수도 있고, 로그아웃 버튼이 없는 문제가 있다.
로그인 하지 않았는데도 home.html로 이동 할 수 있는 문제도 있다.

로그인 해야 home.html로 갈 수 있도록 해보자.

# tweet/views.py 
from django.shortcuts import render, redirect 
def tweet(request): 
    if request.method == 'GET':  # 요청하는 방식이 GET 방식인지 확인하기 
        user = request.user.is_authenticated  # 사용자가 로그인이 되어 있는지 확인하기 
        if user:  # 로그인 한 사용자라면 
            return render(request, 'tweet/home.html') 
        else:  # 로그인이 되어 있지 않다면  
            return redirect('/sign-in')

로그인 되어있으면 회원가입 안들어가게 수정.

# user/views.py 
def sign_up_view(request): 
    if request.method == 'GET': 
        user = request.user.is_authenticated # 로그인 된 사용자가 요청하는지 검사 
        if user: # 로그인이 되어있다면 
            return redirect('/') 
        else: # 로그인이 되어있지 않다면 
            return render(request, 'user/signup.html') 
    elif request.method == 'POST': 
        username = request.POST.get('username', None) 
        password = request.POST.get('password', None) 
        password2 = request.POST.get('password2', None) 
        bio = request.POST.get('bio', None) 
        if password != password2: 
            return render(request, 'user/signup.html') 
        else: 
            exist_user = get_user_model().objects.filter(username=username) 
            if exist_user: 
                return render(request, 'user/signup.html') # 사용자가 존재하기 때문에 사용자를 저장하지 않고 회원가입 페이지를 다시 띄움 
            else: 
                UserModel.objects.create_user(username=username, password=password, bio=bio) 
                return redirect('/sign-in') # 회원가입이 완료되었으므로 로그인 페이지로 이동

로그인 되어있으면 로그인 안들어가지게 수정

# user/views.py 
def sign_in_view(request): 
    if request.method == 'POST': 
        username = request.POST.get('username', None) 
        password = request.POST.get('password', None) 
        me = auth.authenticate(request, username=username, password=password)  # 사용자 불러오기 
        if me is not None:  # 저장된 사용자의 패스워드와 입력받은 패스워드 비교 
            auth.login(request, me) 
            return redirect('/') 
        else: 
            return redirect('/sign-in')  # 로그인 실패 
    elif request.method == 'GET': 
        user = request.user.is_authenticated  # 사용자가 로그인 되어 있는지 검사 
        if user:  # 로그인이 되어 있다면 
            return redirect('/') 
        else:  # 로그인이 되어 있지 않다면 
            return render(request, 'user/signin.html')

로그아웃 버튼 만들고 구현하기.

#user/views.py 
from django.contrib.auth.decorators import login_required

@login_required 
def logout(request): 
    auth.logout(request) # 인증 되어있는 정보를 없애기 
    return redirect("/")
@login_requireduser = request.user.is_authenticated 은 모두 로그인 한 사람들만 사용 할 수 있도록 도와주는 기능
 
로그아웃 urls 추가
# user/urls.py 
from django.urls import path 
from . import views 
urlpatterns = [ 
    path('sign-up/', views.sign_up_view, name='sign-up'), 
    path('sign-in/', views.sign_in_view, name='sign-in'), 
    path('logout/', views.logout, name='logout') 
]
html에 버튼 추가
<!-- templates/base.html --> 
		... 생략  
				<li class="nav-item"> 
            <a class="nav-link" href="#"> 친구 <span class="sr-only"></span></a> 
        </li> 
    </ul> 
</div> 
<form class="form-inline my-2 my-lg-0"> 
    {% if not user.is_authenticated %} 
        <ul class="navbar-nav mr-auto"> 
            <li class="nav-item active"> 
                <a class="nav-link" href="/sign-in"> Sign In <span class="sr-only"></span></a> 
            </li> 
            <li class="nav-item active"> 
                <a class="nav-link" href="/sign-up"> Sign Up <span class="sr-only"></span></a> 
            </li> 
        </ul> 
    {% else %} 
        <ul class="navbar-nav mr-auto"> 
            <li class="nav-item" disabled> 
                <span class="nav-link"> 
                    {{ user.username }} 님 반갑습니다! 
                </span> 
            </li> 
            <li class="nav-item"> 
                <a class="nav-link" href="/logout"> 로그아웃 </a> 
            </li> 
        </ul> 
    {% endif %} 
</form> 
... 생략
<a class="nav-link" href="/logout"> 로그아웃 </a> 부분이 우리의 로그아웃을 도와주는 부분
 

게시글 데이터베이스에 저장하기.

html에서 post로 데이터 보내기.
... 생략 
<form action="/tweet/" method="post"> 
    {% csrf_token %} 
    <div class="form-group mb-2"> 
        <textarea class="form-control" style="resize: none" name='my-content' id="my-content"></textarea> 
    </div> 
    <button type="submit" class="btn btn-primary" style="float:right;">작성하기</button> 
</form> 
... 생략
tweet으로 보냈으니까 url이 어느 함수로 연결 되어있는지 확인해보자.
from django.urls import path 
from . import views 
urlpatterns = [ 
    path('', views.home, name='home'), 
    path('tweet/', views.tweet, name='tweet') 
]
urls 확인하기. views.tweet이니까 views로 가서 tweet 함수를 찾자.
그리고 post로 데이터가 온 것을 저장하자.
from .models import TweetModel # 글쓰기 모델 -> 가장 윗부분에 적어주세요! 
def tweet(request): 
    if request.method == 'GET':  # 요청하는 방식이 GET 방식인지 확인하기 
        user = request.user.is_authenticated  # 사용자가 로그인이 되어 있는지 확인하기 
        if user:  # 로그인 한 사용자라면 
            return render(request, 'tweet/home.html') 
        else:  # 로그인이 되어 있지 않다면 
            return redirect('/sign-in') 
    elif request.method == 'POST':  # 요청 방식이 POST 일때 
        user = request.user  # 현재 로그인 한 사용자를 불러오기 
        my_tweet = TweetModel()  # 글쓰기 모델 가져오기 
        my_tweet.author = user  # 모델에 사용자 저장 
        my_tweet.content = request.POST.get('my-content', '')  # 모델에 글 저장 
        my_tweet.save() 
        return redirect('/tweet')
 
 

게시글 데이터 출력 / 삭제

게시글 출력하기.

데이터를 담아서 home.html에 보내준다.
# tweet/views.py

def tweet(request):
    if request.method == 'GET':  # 요청하는 방식이 GET 방식인지 확인하기
        user = request.user.is_authenticated  # 사용자가 로그인이 되어 있는지 확인하기
        if user:  # 로그인 한 사용자라면
            all_tweet = TweetModel.objects.all().order_by('-created_at') # 여기랑 
            return render(request, 'tweet/home.html', {'tweet': all_tweet}) # 여기가 중요. 
        else:  # 로그인이 되어 있지 않다면
            return redirect('/sign-in')
    elif request.method == 'POST':  # 요청 방식이 POST 일때
        user = request.user  # 현재 로그인 한 사용자를 불러오기
        my_tweet = TweetModel()  # 글쓰기 모델 가져오기
        my_tweet.author = user  # 모델에 사용자 저장
        my_tweet.content = request.POST.get('my-content', '')  # 모델에 글 저장
        my_tweet.save()
        return redirect('/tweet')
이제 html에서 그 데이터를 띄워주면 된다.
<!-- templates/tweet/home.html -->
<hr>
<!-- 작성 된 글이 나오는 곳 -->
<div class="row">
    {% for tw in tweet %}
        <div class="col-md-12 mb-2">
            <div class="card">
                <div class="card-body">
                    <div class="media">
                        <div class="media-body">
                            <h5 class="mt-0">{{ tw.content }}</h5>
                        </div>
                        <div style="text-align: right">
                            <span style="font-size: small">{{ tw.author.username }}-{{ tw.created_at|timesince }} 전</span>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    {% endfor %}
</div>

글 삭제

삭제 기능을 views에 추가한다.
# tweet/views.py
from django.contrib.auth.decorators import login_required


@login_required
def delete_tweet(request, id):
    my_tweet = TweetModel.objects.get(id=id)
    my_tweet.delete()
    return redirect('/tweet')
url을 누르면 views에 기능이 실행되도록 추가한다.
# tweet/urls.py

from django.urls import path
from . import views

urlpatterns = [
    path('', views.home, name='home'),
    path('tweet/', views.tweet, name='tweet'),
    path('tweet/delete/<int:id>', views.delete_tweet, name='delete-tweet'),
]
tweet/delete/<int:id> 는, tweet/delete/123 과 같이 맨 뒷자리에 숫자가 온다는 얘기이고, 이 숫자는 id에 담겨져 delete_tweet에 전달
html에 삭제버튼을 띄워주고 게시글에 id를 대입 해준다.
<!-- templates/tweet/home.html -->
... 생략 

<!-- 작성 된 글이 나오는 곳 -->
<div class="row">
    {% for tw in tweet %}
        <div class="col-md-12 mb-2">
            <div class="card">
                <div class="card-body">
                    {% if tw.author == user %}
                    <div style="text-align: right">
                        <a href="/tweet/delete/{{ tw.id }}">
                            <span class="badge rounded-pill bg-danger">삭제</span>
                        </a>
                    </div>
                    {% endif %}
			<div style="text-align: right"> 
			    <a href="#"> 
				<span class="badge rounded-pill bg-success">보기</span> 
			    </a> 
			</div> 
                    <div class="media">
                        <div class="media-body">
                            <h5 class="mt-0">{{ tw.content }}</h5>
                        </div>
                        <div style="text-align: right">
                            <span style="font-size: small">{{ tw.author.username }}-{{ tw.created_at|timesince }} 전</span>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    {% endfor %}
</div>

... 생략
  • 이 게시글의 author (글쓴이) 와, 로그인 한 사용자가 같을 때에만 '삭제' 버튼이 나타납니다
  • 삭제 버튼은 /tweet/delete/tw.id 로 연결이 되는데, 이 tw.id는 게시글의 고유 id값입니다!

'Django' 카테고리의 다른 글

장고 정리: 5주  (0) 2023.04.12
무신사 ERD  (0) 2023.04.09
파이썬 장고 실무 기초: 4  (0) 2023.04.05
파이썬 장고 실무 기초: 2  (0) 2023.04.04
파이썬 장고 실무 기초: 1  (0) 2023.04.03

장고의 일하는 방식. 이거 엄청 중요.

urls에서는 url 설정과 설정한 url에서 보여줄 html을 연결할 수 있다.

view에서는 url에서 연결한 html을 리턴하도록 함수를 선언할 수 있다.

post방식으로 회원가입이나 로그인 시의 데이터가 들어오는 것도 view에서 받는다.

모델은 회원가입시 어떤 정보들을 저장할지 정한 형식이다.

 

앱 만들기

터미널에 입력하면 각각의 이름으로 기능을 추가 할 수 있도록 폴더와 파일이 만들어진다.

django-admin startapp user #사용자 관리 담당할 user
django-admin startapp tweet #글 관리 담당할 tweet
 
settings.py에서 installed_apps에 꼭 앱의 이름을 추가 해줘야 한다.
 

 

모델 만들기

각 앱에서 사용할 모델들을 만들고 장고에 알려줘야 한다.

python manage.py makemigrations

그리고 데이터베이스에 반영!

python manage.py migrate

 

회원가입 기능

사용자 데이터 post로 요청.

html에서 입력하는 요소들이 post방식으로 전해져 db에 저장할 수 있도록

보안,설정들을 해주고...

사용자 데이터를 db에 저장

post로 온 각각의 데이터를 저장 할 수 있도록 설정을 해줘야한다.

중복 아이디 검사

filter(username=username) 으로 모델에 있는 아이디가 같은 값을 찾아오면 된다.

 

로그인 기능

사용자 데이터 post로 요청

입력한 아이디와 비밀번호를 post로 받아와서...

사용자 데이터 db에서 확인

아이디, 비밀번호를 검증하고 세션에 저장해주면 된다.

 

 

 

프로젝트 구조 만들기

sns기능을 생각하면
사용자 관리(회원가입/로그인/로그아웃)
글쓰기
친구만들기
로 나누어 볼 수 있다.
크게 사용자와 글쓰기로 나누어 볼 수 있고 관련된 앱을 만든다.
터미널에 입력한다.
django-admin startapp user #사용자 관리 담당할 user
django-admin startapp tweet #글 관리 담당할 tweet
user, tweet이라는 앱이 만들어지면서 폴더와 필요한 파일들이 생성된다.
앱이 만들어졌으니 settings.py에서 앱을 사용할 수 있도록 수정 해줘야 한다.
INSTALLED_APPS = [ 
    'django.contrib.admin', 
    'django.contrib.auth', 
    'django.contrib.contenttypes', 
    'django.contrib.sessions', 
    'django.contrib.messages', 
    'django.contrib.staticfiles', 
    'tweet', #
    'user',  # 두개 추가!
]

데이터베이스와 장고 ORM 알아보기

데이터 베이스 연결

장고가 잘 실행되면 데이터베이스가 자동으로 생긴다.
파이참 우측 상단에 있는 데이터베이스를 클릭해서 경로에서 데이터베이스를 찾고 sqlite로 데이터베이스를 연결하고 드라이버를 설치해주면 연결 할 수 있다.
settings.py  밑쪽을 보면 데이터베이스가 생성되도록 적혀져 있다.

ORM

데이터베이스를 객체로 보고 SQL언어가 아닌 클래스로 쉽게 표현, 사용 할 수 있게 해줌. 클래스로 표현한 형태가 모델이다.

유저모델 만들기

유저 모델에 필요한 요소는 무엇일지 고민을 해야한다.
유저이름, 비밀번호, 바이오, 생성일, 수정일을 받기로 정하였다.
메타는 db에 테이블의 이름을 정하고 저장해준다.
각 필드는 어떤 정보가 들어갈 건지 설정할 수 있다.
#user/models.py 
from django.db import models 
# Create your models here. 
class UserModel(models.Model):

    class Meta: 
        db_table = "my_user"

    username = models.CharField(max_length=20, null=False) 
    password = models.CharField(max_length=256, null=False) 
    bio = models.CharField(max_length=256, default='') 
    created_at = models.DateTimeField(auto_now_add=True) 
    updated_at = models.DateTimeField(auto_now=True)

만든 유저모델 관리자 페이지에 넣기

데이터베이스의 변경을 알려줘야한다.

python manage.py makemigrations
변경된 모델의 이름이 출력이 되면 완료.

 

데이터베이스에 변경을 반영해야한다.
python manage.py migrate
관련된 이름이 출력되면 완료.
 

admin 기능 맛보기

/admin 으로 이동하면 관리자 페이지로 갈 수 있다.
관리자로 로그인할 수퍼유저를 만들어야한다.
터미널에 입력!
python manage.py createsuperuser
 
admin에 모델을 불러와서 모델을 만들고 수정 할 수 있도록 할 수 있다.
user의 admin에 추가한다.
from django.contrib import admin
from .models import UserModel



# Register your models here.

admin.site.register(UserModel) # 이 코드가 나의 UserModel을 Admin에 추가 해 줍니다
 

tweet모델 관리자 페이지에 넣기

tweet 모델 먼저 만든다.
# tweet/models.py
from django.db import models
from user.models import UserModel




# Create your models here.
class TweetModel(models.Model):
    class Meta:
        db_table = "tweet"



    author = models.ForeignKey(UserModel, on_delete=models.CASCADE)
    #ForeignKey는 '외부 모델을 가져와서 사용하겠다.' 라는 얘기
    content = models.CharField(max_length=256)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

데이터 베이스에 알려주고 적용하기

python manage.py makemigrations
python manage.py migrate
admin에 넣기
from django.contrib import admin
from .models import TweetModel

# Register your models here.
admin.site.register(TweetModel)

로그인 화면 띄우기

base, signup, signin html을 만들고 각각 이어줘야 한다.
sns에 있는 urls.py에는 user.urls에 있는 url들을 연결 시켜줘야 하고
user.urls는 views의 함수와 연결을 해줘야한다.
총 세가지의 작업이 필요.
sns에 있는 urls.py 수정
# mySpartaSns/urls.py
from django.contrib import admin
from django.urls import path, include



urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('user.urls')) #user앱의 urls.py에 연결시키겠다! 라고 선언 해 주는 코드 
]
유저의 views.py 수정
from django.shortcuts import render


# Create your views here.
def sign_up_view(request):
    return render(request, 'user/signup.html')


def sign_in_view(request):
    return render(request, 'user/signin.html')
유저의 urls.py 수정
from django.urls import path
from . import views

urlpatterns = [
    path('sign-up/', views.sign_up_view, name='sign-up'),
    path('sign-in/', views.sign_in_view, name='sign-in'),
]
 

회원가입 기능 만들기

페이지 보여주기와 가입정보 입력 후 전송 url은 동일.
보여주는 것은 get방식, 데이터 전송은 post 방식
def sign_up_view(request):
    if request.method == 'GET': # GET 메서드로 요청이 들어 올 경우
        return render(request, 'user/signup.html')
    elif request.method == 'POST': # POST 메서드로 요청이 들어 올 경우
        
        return ""
signup.html에서 회원가입 시 데이터를 전송 할 수 있도록 수정해야함.
<!-- 윗 부분 생략 -->
<div class="wrap">
    <h2 class="title-center"> 회원가입 </h2>
    <form class="form-area" method="post" action="/sign-up/">
        {% csrf_token %}
        <div class="form-group mt-2 mb-2">
            <label for="username">이름</label>
            <input type="text" class="form-control" id="username" name="username">
        </div>
        <div class="form-group mt-2 mb-2">
<!-- 아랫 부분 생략 -->
<form>태그의 가장 마지막에 있는 <button type="submit" class="btn btn-primary">회원가입</button> 버튼은, form태그의 method로 action에 데이터를 보내주는 역할
{% csrf_token %} 은, Django에서 post 할 때에 보안을 위해서 사용
회원가입 하면서 적었던 내용이 이제 post 방식으로 오게 되고, 그걸 db에 저장해야한다.
 
from django.shortcuts import render, redirect
from .models import UserModel



def sign_up_view(request):
    if request.method == 'GET':
        return render(request, 'user/signup.html')
    elif request.method == 'POST':
        username = request.POST.get('username', None)
        password = request.POST.get('password', None)
        password2 = request.POST.get('password2', None)
        bio = request.POST.get('bio', None)



        if password != password2:
            return render(request, 'user/signup.html')
        else:
            new_user = UserModel() #나는 괄호를 빼먹어서 에러가 났다. 조심하자. 
            new_user.username = username
            new_user.password = password
            new_user.bio = bio
            new_user.save()
        return redirect('/sign-in')

로그인 기능 만들기

user.views에 POST를 추가하자.
# user/views.py
from django.http import HttpResponse



def sign_in_view(request):
		if request.method == 'POST':
        return HttpResponse("로그인 성공!")
    elif request.method == 'GET':
        return render(request, 'user/signin.html')
 
form태그에 method, action 추가하기.
아이디와 비밀번호 정보를 보내야 하기 때문.
 
<!-- 윗부분 생략 -->
<div class="wrap">
    <h2 class="title-center"> 로그인</h2>
    <form class="form-area" action="/sign-in/" method="post">
        {% csrf_token %}
        <div class="form-group mt-2 mb-2">
<!-- 아랫 부분 생략 -->
user.views에서 아이디와 비밀번호의 정보가 일치하는 유저가 있는지 확인
# user/views.py
def sign_in_view(request):
    if request.method == 'POST':
        username = request.POST.get('username', None)
	password = request.POST.get('password', None) 


        return HttpResponse("로그인 성공!")
    elif request.method == 'GET':
        return render(request, 'user/signin.html')

# user/views.py
def sign_in_view(request):
    if request.method == 'POST':
        username = request.POST.get('username', None)
        password = request.POST.get('password', None)

        me = UserModel.objects.get(username=username)  # 사용자 불러오기
        if me.password == password:  # 저장된 사용자의 패스워드와 입력받은 패스워드 비교
            request.session['user'] = me.username  # 세션에 사용자 이름 저장
            return HttpResponse("로그인 성공!")
        else: # 로그인이 실패하면 다시 로그인 페이지를 보여주기
            return redirect('/sign-in')
    elif request.method == 'GET':
        return render(request, 'user/signin.html')
 
숙제 1: 아이디가 중복이라면 가입이 안되도록 코드 수정.
이거는 몰라서 바로 답안을 봤다. 필터를 배워야한다.
filter(조건 함수, 순회 가능한 데이터)
filter() 함수는 두번째 인자로 넘어온 데이터 중에서 첫번째 인자로 넘어온 조건 함수를 만족하는 데이터만을 반환합니다.
filter(조건 함수, 순회 가능한 데이터)
filter() 함수는 두번째 인자로 넘어온 데이터 중에서 첫번째 인자로 넘어온 조건 함수를 만족하는 데이터만을 반환합니다.
오오~~ 만약 조건 함수가 가입 시 id라면 순회 가능한 데이터가 모델의 id들로 한다면 중복을 찾아 낼 수 있겠구나!
 
숙제 2 : 로그인 시 로그인 id출력.
return HttpResponse(f"안녕하세요{username}님. 로그인 되었습니다.")
이거는 너무 쉬웠구.

'Django' 카테고리의 다른 글

장고 정리: 5주  (0) 2023.04.12
무신사 ERD  (0) 2023.04.09
파이썬 장고 실무 기초: 4  (0) 2023.04.05
파이썬 장고 실무 기초: 3  (0) 2023.04.05
파이썬 장고 실무 기초: 1  (0) 2023.04.03

매일 공부한 내용 정리한 걸 TIL로 제출했는데 이제는 TIL에 한번 더 정리해서 한번 더 복습을 하도록 하자.

그리고 오늘 처음 장고를 시작했는데, 첫째주만 공부해서 그냥 장고가 어떤 것이다 정도만 이해했다.

 

장고와 플라스크

장고는 플라스크랑 다르게 많은 기능이 이미 구현되어있어서 그걸 이용해서 웹 페이지를 만들 수 있는 아주 좋은 웹 프레임워크라는 것.

 

인코딩 에러

그리고 장고 실행시 인코딩 오류가 났는데 설정에서 콘솔 인코딩과 파일 인코딩을 UTF-8로 바꾸어주면 에러를 해결 할 수 있다.

 

[ ] vs get

대괄호를 통해 딕셔너리 키 값을 인덱싱해서 밸류를 가져오는 경우와

get으로 가져오는 경우는 전자는 키 값이 없을 때 에러가 나지만 후자는 None을 출력한다는 것.

 

그리고 현직 개발자분의 특강도 있었다.

관한 내용은 특강에 글을 남겼다.

중요한것은 메타인지와 본인의 성장이었다.

가장 나에게 필요했던 것은 악에 받친 감정으로 뭐든지 해내고 말겠다는 마음이 가장 필요하지 않나..

'TIL' 카테고리의 다른 글

[18일차] TIL : 오늘 뭘 했나...  (0) 2023.04.06
[17일차] TIL : 장고 1주차 2주차  (0) 2023.04.05
파이썬 개인과제 해설 정리.  (0) 2023.04.01
TIL super() , return  (0) 2023.03.29
[5일차] TIL : TIL 작성 잘 해야 크게 간다!  (0) 2023.03.17

어떻게 학습하고, 어떻게 적응하고, 어떻게 일해야 할까

어떻게 학습 할까?

  • 나는 나를 얼마나 알고 있나요
내가 뭘 모르고, 뭘 알고 있는지 : 메타인지
TIL과 WIL이 메타인지를 확인 하는 방법.
  • 개발공부는 왜 이렇게 힘든걸까?
공부해야할게 엄청 많음 ai, 머신러닝, 데이터 등등 연봉 1억은 당연히 어려움.
힘들기 때문에 가치가 있는 것.
  • 열심히 하는 사람, 잘하는 사람보다 더 잘 학습하는 법
악에 받친 감정. 오롯이 '해내고 말겠다'는 마음.
  • 번아웃은 언제 올까요?
오늘 할 일을 감당 할 수 없을 때, 오늘 공부해야 할 내용을 가늠할 수 없을 때 온다.
오늘의 일을 해냄으로 내일의 번아웃을 방지한다.
 

어떻게 적응할까?

  • 삼성SDDS 현직 개발자가 알려주는 신입이 적응하는법
질문의 적정성을 잘 찾아서 적극적을 질문하며 업무에 임하는 자세가 중요. 메타인지가 중요.
개인의 메타인지력과 조직의 메타인지력
  • 네이버 현직 개발자가 알려주는 신입이 적응하는법
적극적으로 질문, 겸손, 과감함, 기록하는 습관
  • 테슬라 CEO 일론 머스크가 알려주는 신입을 뽑는 기준
팀원을 뽑을때 : 문제를 세부사항까지 정확히 해결 할 수 있는 사람.
 

어떻게 일해야할까?

  • 직업을 가지는 개발자가 되자
개발자로서 대체하기 어려운 인력이 되어야 한다. 회사에서 실전 경험과 문제의 해결이 중요.
지식은 베이스.
  • 진심으로 개발하는 개발자
맡은 서비스를 잘 개발하는 개발자.
  • 겸손이 중요
  • 살아있는 코드 작성.
코드를 통해 의도를 전달
팀과 일관된 코드 스타일
하나의 역할만 담당.
매개변수를 명확하게
예측 가능한 코드
부수효과 제거
중요한 입력에 대해 무시하지 마라
테스트 코드를 통해 목숨을 하나 더.
원시값을 포장
변경 가능성을 최소화하라
  • 채용시장에서 나의 무기를 계속해서 점검하자!
채용공고를 주기적으로 확인. 나의 무기를 단련해야함.
 
 
개발이 주가 되는 회사를 가는게 좋다.
좋은 포트폴리오는 팀원들과 프로젝트하면서 문제점을 어떻게 해결하려고 시도하고 해결했는지를 보여줄 수 있는 것.
포트폴리오나 자소서에 미끼들을 던져놓고 면접관의 질문들은 내가 말을 많이 할 수 있게 해서 주도권을 가져올 수 있다.
자소서에서 쓸 키워드 내용들 : 채용공고, 회사소개, CEO인사말, 인재상, 최신뉴스
 
책 추천

타이탄의 도구

'특강' 카테고리의 다른 글

좋은 개발자의 비밀  (0) 2023.03.20

+ Recent posts