데이터 베이스 관계
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 |