데이터 베이스 관계

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

+ Recent posts