본문 바로가기
DoItDJango

텍스트 콘텐츠를 저장하는 모델 만들기

by 자동매매 2023. 4. 14.
게시판 게시물의 텍스트 콘텐츠를 저장하는 모델을 만들려고 하며, 다음과 같이 할 수 있습니다.

 

강력한 Django ORM (Object-Relational Mapper) 덕분에 PostgreSQL, MySQL, MariaDB, Oracle 또는 SQLite 같은 여러 데이터베이스 백엔드에 대한 지원이 내장되어 있습니다. 즉, 개발자로서 models.py 파일에 동일한 코드를 작성할  있으며 자동으로  데이터베이스로 올바르게 변환됩니다. 필요한 유일한 구성은 settings.py 파일의 DATABASES 섹션을 업데이트하는 것입니다. 이것은 정말 인상적인 기능입니다!

 

1. 프로젝트 root에 posts App생성

python manage.py startapp posts

 

2. app 등록

# mb_project/settings.py 
INSTALLED_APPS = [
	'django.contrib.admin', 
    'django.contrib.auth', 
    'django.contrib.contenttypes', 
    'django.contrib.sessions', 
    'django.contrib.messages', 
    'django.contrib.staticfiles', 
    'posts.apps.PostsConfig',         # new
]

 

3. migrate

migrate 명령을 실행하여 Django의 기본 설정에 따라 초기 데이터베이스를 만듭니다.
python manage.py migrate

기술적으로 db.sqlite3 파일은 migrate 또는 runserver를 처음 실행할  생성되지만 migrate는 프로젝트에 포함되고 INSTALLED_APPS에 나열된 데이터베이스 모델의 현재 상태와 데이터베이스를 동기화합니다. 즉, 데이터베이스가 프로젝트의 현재 상태를 반영하도록 하려면 모델을 업데이트할 때마다 migrate(및 makemigrations)를 실행해야 합니다. 이에 대한 자세한 내용은  설명하겠습니다.

 

4. Create a database model

posts/models.py

from django.db import models

# Create your models here.
class Post(models.Model):
    text = models.TextField()   # 텍스트 형식 지정

 

[ 참조 ] model fields

 

5.  Activate models

  1. makemigrations 명령을 사용하여 마이그레이션 파일을 만듭니다. 
    마이그레이션 파일은 데이터베이스 모델에 대한 모든 변경 사항에 대한 참조를 생성하므로 시간이 지남에 따라 변경 사항을 추적하고 필요에 따라 오류를 디버그할 수 있습니다.
  2. 마이그레이션 파일의 지침을 실행하는 migrate 명령을 사용하여 실제 데이터베이스를 빌드합니다.
python manage.py makemigrations posts 
python manage.py migrate

1개의 앱에서는 makemigration 뒤에이름을 포함할 필요는 없습니다. 하지만 여려 앱을 구동할 경우 꼭 지정하라!!!

 

6. Django Admin 설정

Django의 강력한 내장 관리 인터페이스입니다. 

Django가 원래 신문 CMS(콘텐츠 관리 시스템)로 구축되었기 때문에 생겨났습니다. 

저널리스트가 "코드" 건드릴 필요 없이 관리자에서 기사를 작성하고 편집할  있다는 것이었습니다. 

 

1. 관리자를 사용하려면 먼저 로그인할  있는 수퍼유저를 생성해야 합니다. 

명령줄 콘솔에서 python manage.py createsuperuser 입력하고 사용자 이름, 이메일  암호를 입력

2. 서버 재구동
 
3. http://127.0.0.1:8000/admin/ 접속 확인

4. posts확인

앱을 INSTALLED_APPS에 등록하듯이 admin.py 파일 관리자 찿에게 표시되도록 업데이트해야 합니다. 텍스트 편집기에서 posts/admin.py열고 다음 코드를 추가하면 포스트 모델이 표시됩니다.

from django.contrib import admin
from .models import Post

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

5. post추가해보기

데이터베이스에 대한  번째 게시판 게시물을 만들어 보겠습니다. 게시물 반대편에 있는 + 추가 버튼을 클릭하고 텍스트 양식 필드에 자신의 콘텐츠를 입력합니다.

 

그런 다음 "저장" 버튼을 클릭하면 기본 게시물 페이지로 리디렉션됩니다. 그러나 자세히 살펴보면 문제가 있습니다 : 우리의 새로운 항목은 "Post object"로 표시된다

 

6. model.py 를 수정하여 Post object -> Tex로 변경

from django.db import models

# Create your models here.
class Post(models.Model):
    text = models.TextField()   # 텍스트 형식 지정
    def __str__(self):
        return self.text[:200]

 

7. Views/Templates/URLs 설정

홈페이지에 데이터베이스 콘텐츠를 표시하려면 뷰, 템플릿  URLConfs를 연결해야 합니다.  패턴은 이제 친숙하게 느껴지기 시작할 것입니다. 

내장된 일반 Template-View 사용하여 홈페이지에 템플릿 파일을 표시했습니다. 이제 데이터베이스 모델의 내용을 나열하려고 합니다. 다행스럽게도 이것은  개발에서 일반적인 작업이며 Django에는 일반 클래스 기반 ListView 장착되어 있습니다.

 

7.1 view 파일 정의

posts/view.py

from django.views.generic import ListView
from .models import Post
# Create your views here.
class HomePageView(ListView):
    model = Post
    template_name = "home_posts.html"

 

7.2 templates 폴더 생성 및 등록 그리고 파일 생성

1) posts폴더 내에 templates 폴더 생성 및 setting.py에 등록

TEMPLATES = [
    {
           ....
        'DIRS': [Path(BASE_DIR).joinpath('posts','templates')],
           ....
    }

2)  template 파일 생성

ListView는 자동으로 object_list를 반환한다(for문용). 객체의 text에 억세스하여 표시한다.

<h1>Message board homepage</h1>

<ul>
    {% for post in object_list %}
    <li>{{ post.text }}</li>
    {% endfor %}
</ul>

 

3) 더친숙한 context objec name 사용을 위해 view정의 변경

class HomePageView(ListView): 
    model = Post
    template_name = 'home_posts.html' 
    context_object_name = 'all_posts_list' # new

 

<h1>Message board homepage</h1>

<ul>
    {% for post in all_posts_list %}  <!-- object_list  도 사용 가능 -->
    <li>{{ post.text }}</li>
    {% endfor %}
</ul>

 

7.3  URLConfs 설정

project / urls.py

from django.urls import path, include # new
from django.contrib import admin


urlpatterns = [

    path('admin/', admin.site.urls), 
    path('', include('posts.urls')),  # new
]

 

posts / urls.py

from django.urls import path
from .views import HomePageView


urlpatterns = [
    path('posts/', HomePageView.as_view(), name='home_posts'),
]

 

7.4 Test

  • http://127.0.0.1:8000/posts 로 posts확인 가능
  • 관리자 모드에서 post 생성 확인 가능

 

 

 

posts / test.py

 

$ python manage.py test

 

이전에는 정적 페이지만 테스트했기 때문에 SimpleTestCase를 사용했습니다. 하지만 이제 홈페이지가 데이터베이스와 함께 작동하기 때문에 TestCase를 사용해야 하며, 이를 통해 확인할 수 있는 "테스트" 데이터베이스를 만들 수 있습니다. 즉, 실제 데이터베이스에서 테스트를 실행할 필요가 없지만 대신 별도의 테스트 데이터베이스를 만들고 샘플 데이터로 채운 다음 더 안전하고 성능이 뛰어난 접근 방식에 대해 테스트 할 수 있습니다.
먼저 텍스트 데이터베이스 필드에 샘플 게시물을 추가한 다음 데이터베이스에 올바르게 저장되었는지 확인하겠습니다. 우리의 모든 테스트 메소드는 test_라는 문구로 시작하여 Django가 테스트 할 수 있도록하는 것이 중요합니다! 코드는 다음과 같습니다.

from django.test import TestCase
from .models import Post

# Create your tests here.
class PostModelTest(TestCase):
    def setUp(self): 
        Post.objects.create(text='just a test')
    def test_text_content(self): 
        post = Post.objects.get(id=1) 
        expected_object_name = f'{post.text}'
        self.assertEqual(expected_object_name, 'just a test')
 

맨 위에는 샘플 데이터베이스와 Post 모델을 만들 수 있는 TestCase 모듈을 가져왔습니다. PostModelTest라는 새 클래스를 만들고 setUp 메서드를 추가하여 'just a test'라는 문자열이 포함된 텍스트 필드가 있는 게시물이라는 하나의 항목만 있는 새 데이터베이스를 만들었습니다. 그런 다음 첫 번째 테스트인 test_text_content를 실행하여 데이터베이스 필드에 실제로 테스트만 포함되어 있는지 확인할 수 있습니다. Post 모델의 첫 번째 ID를 나타내는 post라는 변수를 만들었습니다. 다음 줄은 파이썬 3.6에 추가된 f 문자열을 사용하는데, 변수를 대괄호 {}로 둘러싸고 있는 한 문자열에 직접 변수를 넣을 수 있습니다. 여기서는 expected_object_name post.text의 값 문자열로 설정하는데, 이는 단지 테스트여야 합니다. 마지막 줄에서 assertEqual을 사용하여 새로 만든 항목이 실제로 맨 위에 입력한 항목과 일치하는지 확인합니다. 계속해서 python manage.py test 명령을 사용하여 명령줄에서 테스트를 실행합니다.

 

이러한 모든 테스트를 HomePageViewTest라는 새 클래스에 포함할 수 있습니다. 뷰 이름에 직접 액세스하는 대신 역방향으로 가져 와서 home의 명명 된 URL을 참조합니다. 왜 이렇게합니까? URL 스키마는 프로젝트 과정에서 변경될 수 있고 변경될 수 있지만 명명된 URL은 변경되지 않을 가능성이 높으므로 테스트를 미래에 대비할 수 있는 방법입니다.
역방향의 경우 상단에 가져오기를 하나 더 추가하고 테스트를 위해 새로운 클래스 HomePageViewTest를 추가해야 합니다.

 

 

from django.test import TestCase
from django.urls import reverse  # new
from .models import Post

# Create your tests here.
class PostModelTest(TestCase):
    def setUp(self): 
        Post.objects.create(text='just a test')
    def test_text_content(self): 
        post = Post.objects.get(id=1) 
        expected_object_name = f'{post.text}'
        self.assertEqual(expected_object_name, 'just a test')


class HomePageViewTest(TestCase):  # new
    def setUp(self):
        Post.objects.create(text='this is another test')
    def test_view_url_exists_at_proper_location(self): 
        resp = self.client.get('/') 
        self.assertEqual(resp.status_code, 200)
    def test_view_url_by_name(self):
        resp = self.client.get(reverse('home'))
        self.assertEqual(resp.status_code, 200)
    def test_view_uses_correct_template(self): 
        resp = self.client.get(reverse('home')) 
        self.assertEqual(resp.status_code, 200)
        self.assertTemplateUsed(resp, 'home.html')

 

 

'DoItDJango' 카테고리의 다른 글

Forms  (0) 2023.04.15
Blog App  (0) 2023.04.15
Django Admin 사용  (0) 2023.04.14
Heroku  (0) 2023.04.14
template 사용 - class기반 뷰어 생성  (0) 2023.04.13

댓글