one - to - many
한명의 글쓴이가, 여러개의 글을 작성할 수 있다.
one - to - one
하나의 사용자는 하나의 정보만 가져갈 수 있다.(예:프로필)
many - to - many
피자와 토핑
피자는 여러 토핑을 올릴 수 있고
토핑도 여러 피자위에 토핑으로 올라 갈 수 있다.
터미널 입력
django-admin startapp restaurant
추가한 앱 등록하기
1. restaurant app이 추가된걸 확인한다.
2. 프로젝트의 settings.py 이동
3. INSTALLED_APPS 리스트에, 추가한 앱을 등록한다.
# 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
from django.contrib import admin
from .models import MyTopping, MyPizza
# Register your models here.
admin.site.register(MyPizza)
admin.site.register(MyTopping)
python manage.py createsuperuser
save를 누르는 순간 에러가 발생하는데 이는 admin 게정이 잘못된 경우가 있어
수정을 해줘야 한다.
tweet app, user app, restaurantapp의
migrations 디렉토리의 init을 제외한 파일 제거
마찬가지로 데이터베이스도 삭제한다.
새로운 데이터 베이스 생성
python manage.py makemigrations
python manage.py migrate
새로 생성된 database를 드래그앤 드롭으로 적용
super user 생성
python manage.py createsuperuser
>>> 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: 피망>]>
many to many : 서로를 참조한다.
팔로우 - 팔로워 기능 응용 가능
헤더 추가
from django.conf import settings
프로젝트의 settings파일 import
class UserModel(AbstractUser):
#장고의 기본 모델을 상속받는다.
class Meta:
db_table = "my_user"
bio = models.CharField(max_length=256, default='')
follow = models.ManyToManyField(settings.AUTH_USER_MODEL,related_name='followee')
사용자가 사용자 모델을 참조한다.
AUTH_USER_MODEL
우리의 모델을, 우리가 ManyToManyField로 참조하겠다.
follo필드 안에 들어가는 정보들은 사용자 정보가 된다.
모델을 추가했으니, Django에게 새로운 모델생성을 알리고 적용해야한다.
터미널 입력
python manage.py makemigrations
python manage.py migrate
데이터 베이스가 성공적으로 생성되었다.
@login_required
def user_follow(request, id):
me = request.user
# me : 로그인한 사용자
click_user = UserModel.objects.get(id=id)
#click_user : 로그인한 사용자가 팔로우하거나 팔로우 취소할 사용자
# 해당 사용자의 id의 모델을 가져온다.
if me in click_user.followee.all():
click_user.followee.remove(request.user)
else:
click_user.followee.add(request.user)
return redirect('/user')
click_user가 팔로우하는 모든 데이터를 가져온다.
그 데이터속에 me가 포함되어 있지 않다면 me는 상대방을 팔로우 하고 있지 않는다.
- 예시) 버튼을 클릭하면, 동작된다면
- 동작 : 팔로우 중이면 팔로우
- 동작 : 팔로우 중이 아니라면, 팔로우
from django.urls import path
from . import views
urlpatterns = [
# 회원가입,로그인,로그아웃 기능 생략
path('user/', views.user_view, name='user-list'),
path('user/follow/<int:id>/', views.user_follow, name='user-follow')
]
{% extends 'base.html' %}
base.html을 확장해서 사용한다.
{{ user.username }}
user.(로그인한 유저의 어떠한 정보를 가져온다.)
{{ user.followee.count }}
나를 팔로우한 사람들
{{ user.follow.count }}
내가 팔로우 하는 사람들
{% for ul in user_list %}
users app의 views.py에서 건내온 user_list를 반복문을 돌며
사용자 정보들을 하나하나씩 사용한다.
{{ ul.username }}<
리스트의 반복자가 ul이므로, user_list에 담긴 사용자들의 정보, 이름 이메일 등등 사용할 수 있다.
users app의 models.py
follow = models.ManyToManyField(settings.AUTH_USER_MODEL,related_name='followee')
follow : 내가 팔로우 하는사람
'followee' : 나를 팔로우 하는 사람
다시 돌아와서 템플릿의 user_list.html
{% if ul in user.follow.all %}
<a href="/user/follow/{{ ul.id }}" class="card-link">[팔로우 취소]</a>
{% else %}
<a href="/user/follow/{{ ul.id }}" class="card-link">[팔로우]</a>
{% endif %}
가져온 사용자의 데이터에 user가 팔로우 하는 정보가 있다면
팔로우 취소 창을 띄우고,
없다면 팔로우 창을 띄운다.
<a class="nav-link" href="/user"> 친구 <span class="sr-only"></span></a>
href 속성을 /user로 변경한다.