ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Python/Django] models.Foreingkey many to one 이해하기
    programming/django 2022. 7. 25. 00:48

    Django models.Foreingkey()에 대해서 알아보겠습니다.

    foreingkey 는 many to one 혹은 one to many 관계를 지원하는 메서드 되겠습니다.

    한명의 부모가 여러 자식을 가질 수 있다고 생각하시면 좋을 듯 합니다.

    부모1 -> 자식1, 자식2, 자식3,,,

    자식1 -> 부모1 , 자식2 -> 부모1, 자식3->부모1

     

    그럼 이것을 장고 문서의 예제인, 기사에 대해 만들어 보겠습니다.

    기자는 여러개의 기사를 쓸 수 있지만

    기사는 여러명의 기자를 가질 수 없다는 겁니다.(실제로는 하나의 기사에 여러명의 기자가 투입될 수 있겠죠..?)

     

    Article(기사) DB를 만들고 Reporter(기자) DB를 만들어서 연결해 주겠습니다.

    왜 Article DB에 reporter attribute를 만들지 않고 DB를 따로 만드나요??

    어떤 기능을 원하느냐에 따라서 나눠주냐, 합치느냐는 본인의 편의와 기능에 따라 만들면 되겠습니다.(제 생각)

    이번 글에서는 Foreingkey에 이해를 위해서 나눈 것으로 생각하셔도 좋을 듯합니다.

     

    흐름은 파악해보겠습니다.

    1. models.py에 두개의 클래스, Reporter와 Article을 만든다.

    2. Article 속성에 reporter의 속성을 추가하는데 foreingkey로 Reporter와 연결해 준다.

    3. admin페이지 혹은 shell을 통해 Reporter를 등록한다.

    4. 3번 방식으로 Article을 등록한다.

    5. 데이터를 html에 표시하기!!

     

     

    1. models.py에 두개의 클래스, Reporter와 Article을 만든다.

    2. Article 속성에 reporter의 속성을 추가하는데 foreingkey로 Reporter와 연결해 준다.

    class Reporter(models.Model):
        last_name = models.CharField(max_length=200)
        first_name = models.CharField(max_length=200)
        email = models.EmailField()
        #객체가 호출됐을 때 리턴하는 값이 되겠습니다.
        def __str__(self):
            return '%s %s' % (self.last_name, self.first_name)
    
    
    class Article(models.Model):
        headline = models.CharField(max_length=200)
        pub_date = models.DateField(auto_now_add=True)
        # Report와 연결하고, Reporter의 객체 유무에 따라 지워지겠습니다.
        # ex) 리포터가 회원 탈퇴 시, 그가 쓴 기사들도 지워지는 것
        reporter = models.ForeignKey(Reporter, on_delete = models.CASCADE)
    
        def __str__(self):
        	# 예제는 self.headline입니다.
            return self.headline + f'-{self.reporter.last_name}'
        
        #Meta는 확인이 필요하나 admin이나 데이터를 입맛에 변경할 수 있는 클래스로 보시면 될 듯합니다
        class Meta:
        	# headline을 기준으로 정렬하겠다.
            ordering = ['headline']

    3. admin페이지 혹은 shell을 통해 Reporter를 등록한다.

    3-1. admin 페이지를 등록

    admin 페이지에 Aricle과 Reporter가 보여지려면 만든 앱 내의 admin에 등록해주시면 되겠습니다.

    프로젝트파일/앱파일/admin.py

    from django.contirb import admin
    #만든 모델들
    from .models import Article, Reporter
    
    admin.site.register(Reporter)
    admin.site.register(Article)

    저장을 하고 python manage.py runserver를 통해 서버를 실행해주고 http://127.0.0.1:8000/admin/에 들어가 주시면 되겠습니다.

    그리고 Reporter를 등록해 주시면 되겠습니다.

    3-2. shell을 통해 등록

    python manage.py shell
    
    >>> from 앱이름.models import Reporter, Article
    >>> 리포터1 = Reporter(last_name = '경민', first_name = '김', email = 'test@naver.com')
    >>> 리포터1.save()

    shell을 통한 방법은 시각적으로 편하지 않지만 알아두시면 테스트 데이터로 많은 article을 만들 때 편하실겁니다.

     

    4. 3번 방식으로 Article을 등록한다.

    Reporter의 데이터를 먼저 만든 것은 Article에는 reporter의 속성 값이 포함되어야 하기 때문입니다.

    Reporter 모델에서 설정해 준대로 (경민 김) 나오는 것을 볼 수 있습니다.(제가 last_name과 first_name을 반대로 썼네요)

     

    5. 데이터를 html에 표시하기!!

    5-1. url 설정하기

    5-2. url에 접속시 호출할 함수 구현하기

    5-3. 함수에서 보낼 html 파일 만들기 

    5-4. 확인하기

    먼저 몇개의 Article을 만들었습니다.

    5-1. url 설정하기

    프로젝트를 만들 때 처음 생성된 파일안에 urls.py에 들어가시면 되겠습니다.

    from django.contrib import admin
    from django.urls import path,include
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        #저는 polls 라는 앱을 만들었기에 설정이 이런 것입니다.
        #polls/로 들어오는 것은 polls.urls 파일을 참조하라는 뜻
        path('polls/', include('polls.urls')),
    ]

     

    polls/urls.py 파일

    from django.urls import path
    from . import views
    
    app_name = 'polls'
    urlpatterns = [
    #아무것도 안 들어왔을 때 - https://..../polls/
        #views파일에 있는 index함수를 실행 시켜줄 것이다. name은 여기서는 알 필요x
        path('', views.index, name = 'index'),
    ]

    5-2. url에 접속시 호출할 함수 구현하기

    polls/views.py 파일

    from django.shortcuts import render
    from .models import Article, Reporter
    
    def index(request):
    	#Article의 객체들 모두 가져오겠다.
        a = Article.objects.all()
        #Article의 객체들에서 reporter 의 id가 1인 것을 가져오겠다.
        #객체가 생성될 때 id값은 장고에서 자동으로 생성해줍니다.
        b = Article.objects.filter(reporter_id = 1)
        #Article의 객체에서 reporter의 last_name이 윤민인 것을 가져오겠다.
        #last_name은 Article의 하위 속성이 아니지만 foreingkey로 
        #Reporter의 속성을 가져왔기에 더블언더스코어를'__' 사용하여 속성값을 사용할 수 있습니다.
        c = Article.objects.filter(reporter__last_name = '윤민')
        
        context = {
            'articles1' : a,
            'articles2' : b,
            'articles3' : c,
        }
        
        #요청과, context를 담아 index.html을 보내겠다.
        return render(request, 'polls/index.html', context)

    5-3. 함수에서 보낼 html 파일 만들기 

    원하시는 스타일로 만드시면 되겠습니다.

     

    5-4. 확인하기

    {% for article in articles %}
      <div>
        {{ article }}
        {{ article.headline }}
        {{ article.reporter }}
      </div>
    {% endfor %}

    오타는 차차..

    출처 https://docs.djangoproject.com/en/4.0/topics/db/examples/many_to_one/

     

    Many-to-one relationships | Django documentation | Django

    Django The web framework for perfectionists with deadlines. Overview Download Documentation News Community Code Issues About ♥ Donate

    docs.djangoproject.com

     

    'programming > django' 카테고리의 다른 글

    [Python/Django] ManyToManyFeild 이해하기  (0) 2022.09.05

    댓글

Designed by Tistory.