Relations - 다대일 관계

210801, 210803

다대일 관계 - author (작성자) 추가하기

다대일 관계

A모델의 여러 레코드가 B모델의 한 레코드에 연결될 수 있는 관계

  • 한 유저가 여러개의 포스트를 작성했을 때 포스트라는 여러 레코드가 유저라는 한 레코드에 연결된다

위 관계를 가지는 작성자 필드를 추가할 것임

models.py

from django.contrib.auth.models import User

class Post(models.Model):
    author = models.ForeignKey(User, on_delete=models.CASCADE)
    
def __str__(self):
    return f"{self.pk} {self.title} :: {self.author}"    
  • 외래키 필드를 추가한다. 이 때 on_delete 속성은 만약 author가 삭제되었을 경우, 해당 포스트를 삭제할 것이냐고 묻는 것이다.

    • cascade는 삭제하라는 뜻이며 6가지의 속성을 설정할 수 있다.

    • 여기 참고

  • 이 때 migrations을 진행하면 다음과 같은 텍스트가 뜨는데, default값을 정해달라는 뜻이다.

    • 1번은 migration 할테니, default를 지금 정해달라.

    • 2번은 migration를 취소하고 default를 정하라

여기서는 1을 누른다.

그리고 1을 입력한다. 그러면 1번째 사용자의 이름이 기본 이름으로 설정된다.

연결된 레코드가 삭제될 때 동작 결정하기 - CASCADE, SETNULL

다음과 같이 on_delete 속성을 SET_NULL로 설정할 수도 있다. 이 때 반드시 null=True를 같이 설정해줘야 한다.

이 때 포스트를 작성한 적 있는 유저를 삭제하면 해당 포스트의 이름은 None으로 남게 된다.

포스트 목록, 포스트 상세 페이지에 작성자 추가하기

tests.py 에서는 매번 테스트를 진행할 때 마다 DB가 초기화되었다고 가정하고 실행된다. 이 때 setUp 함수에서 이러한 데이터를 미리 초기화해줄 수 있다.

tests.py

Category 만들기

models.py

  • unique 속성은 동일한 name을 가진 카테고리가 없도록 설정하는 것

  • Meta 클래스를 추가하고 verbose_name_plural 변수를 추가하면 Categorys 항목의 이름을 바꿀 수 있다

  • 마이그리에션 작업 할 것

admin.py

  • 관리자 계정에서 카테고리 페이지를 볼 수 있도록 추가한다.

  • 이 때 CategoryAdmin(admin.ModelAdmin) 클래스를 추가하고 admin.site.register 에 이 클래스를 인자로 받으면 category name이 입력될 때 slug도 동일하게 같이 입력되게 된다.

blank = True vs null = True

  • blank = True : 데이터 폼을 작성할 때 필수적이어야 되는지에 대한 선택지

  • null = True : 데이터베이스에 마이그레이트 될 때 해당 필드가 필수적이어야 되는지에 대한 선택지

  • author를 설정하고, author가 탈퇴해서 해당 게시물의 author가 None 이 더라도 null = True로 되어있으면 상관없다.

django shell로 다대일구조 연결 확인

기존 쉘은 다음과 같다

무언가 칙칙하게 느껴질 수 있다. 이 때 쓸 수 있는 것이 있다. 일단

pip install django_extensions, ipython 을 한다. 그리고 settings.pyINSTALLED_APPSdjango_extensions 를 추가해준다.

그러면 다음과 같이 바뀐 모습을 볼 수 있다.

  • 일단 색이 추가되어서 가독성이 좋아졌다.

  • 그리고 따로 import를 하지 않아도 된다.

그 외에도 이런것들이 된다.

포스트 목록 페이지 수정하기 1

일단 지금까지 작성한 tests.py 를 정리해보자

첫번째, 각 테스트마다 포스트를 만들었다. 네비게이션도 한번에 관리하기 위해서 함수로 만들었는데 포스트도 동일하게 관리할 수 있지 않을까? 이 때 카테고리까지 고려해서 관리해보자

따라서 SetUp을 다음과 같이 수정한다.

tests.py

그리고, 이후에 나오는 post에 관한 코드들을 self.post로 바꾸어준다.

이제, 포스트가 3개로 고정되었다. 따라서 test를 할 때 post가 있을때와 없을 때로 나누어준다.

포스트 목록 페이지 수정하기 2

위 페이지의 카테고리 박스처럼 하려고한다. 이 때 이 항목은 Model의 Category를 참조해야한다. 또, Post 개수에 대한 정보도 얻어야 한다. 이는 일단 여기서 먼저 손보자

views.py

다음과 같이 함수를 추가해줘서, 카테고리 정보를 가져올 수 있도록 한다.

그리고 실제로 템플릿에서도 보일 수 있도록 수정해준다

base.html

그리고 post_list.html 에 카테고리 항목을 보여주는 뱃지를 추가해준다.

  • 이 때 float-right는 오른쪽으로 정렬되게 한다.

    • 부트스트랩에서 지원하는 기능

포스트 상세 페이지 수정하기

post_detail.html 도 마찬가지로 수정해준다.

늘 주의할 것은 p.category 가 아니라 post.category!

카테고리 페이지 만들기

이러한 구조를 가지는 것이 목표. 이 때 이 페이지는 카테고리 카드에 있는 항목을 클릭했을 때 이동하는 페이지이다.

views.py

이전에 index.html을 만드는 것 처럼 class가 아니라 함수로 만들어준다. 이 때 slug미분류일때의 categorypost_list를 따로 정의해줘야 한다.

models.py

위와 같이 Post class와 동일하게 get_absolute_url 함수를 정의해준다. 이 때 주소는 /blog/category/slug/ 가 될 수 있도록 한다.

근데, 나도 어떻게 새로운 url에 페이지가 새로운 템플릿 없이 구성된 것인지 잘 모르겠다.. 아마 기존 템플릿에 조건문으로 덮어쓴 것 같다는 예상 뿐... ㅠㅠ

Last updated

Was this helpful?