Django에서 사용자 지정 manage.py 명령 만들기

18081 단어 tutorialdjangopython
Django를 사용해 본 적이 있다면 다음과 같은 다양한 작업을 실행하기 위해 Django의 manage.py 명령을 사용했을 것입니다.
  • python manage.py runserver
  • python manage.py migrate
  • python manage.py createsuperuser

  • 설명서( django-admin and manage.py )를 보면 사용할 수 있는 유용한 내장 명령이 많이 있습니다. 예를 들어:

  • dumpdata - 앱에서 JSON 또는 다른 형식으로 데이터 내보내기

  • loaddata - 데이터를 데이터베이스로 가져오기

  • migrate - 데이터베이스를 현재 모델 세트 및 마이그레이션과 동기화

  • 가질 수 있는 관리 작업을 위해 고유한 명령을 작성할 수도 있습니다. 예를 들어 예약된 유지 관리를 수행하려는 경우 이러한 명령을 빌드하고 예약된 작업으로 실행할 수 있습니다(예: celery 을 통해).

    이 기사에서는 API 요청의 데이터를 데이터베이스에 채우는 사용자 정의 manage.py 명령을 작성하는 방법을 보여줍니다.

    이 샘플 Django 앱의 전체 소스 코드는 GitHub에서 찾을 수 있습니다.

    대본



    어떤 이유로 우리가 가지고 있는 데이터베이스 모델을 API의 일부 맥주 데이터로 채우고 싶다고 가정해 보겠습니다. 맥주에 관심이 있다면 Brewdog에 "Hello, my name is..."라는 이름의 맥주 시리즈가 있었던 것을 기억할 것입니다.

    https://punkapi.com의 무료 API에서 해당 맥주에 대한 정보를 얻을 수 있습니다.



    맥주 데이터 미리보기

    장고 모델



    Django 앱에서 데이터 모델을 빌드합니다.

    # models.py
    from django.db import models
    
    
    class Beer(models.Model):
        name = models.CharField(max_length=100)
        tagline = models.CharField(max_length=200)
        first_brewed = models.CharField(max_length=20)
        description = models.TextField()
        added = models.DateTimeField(auto_now_add=True)
        edited = models.DateTimeField(auto_now=True)
    
        def __str__(self):
            return f'Beer: {self.name}'
    
    


    모델을 데이터베이스로 마이그레이션합니다.

    $ python manage.py makemigrations beers
    
    $ python manage.py migrate
    


    사용자 지정 명령 빌드



    새 명령을 추가하려면 프로젝트의 apps 폴더 아래에 폴더 구조를 만듭니다.

    Django documentation에서 인용

    To do this, add a management/commands directory to the application. Django will register a manage.py command for each Python module in that directory whose name doesn’t begin with an underscore



    따라서 이 경우 다음 폴더에 update_beers.py를 만듭니다.

    beers/
        __init__.py
        models.py
        management/
                __init__.py
                commands/
                update_beers.py 
    
    


    명령 코드



    명령 코드에는 Djangos BaseCommand의 하위 클래스인 Command 클래스가 포함되어야 합니다. BaseCommand에는 구현해야 하는 메서드가 하나 있는데, 바로 handle 메서드입니다. 그것은 우리 명령의 논리를 포함할 것입니다.

    필요한 코드의 기본 구조는 아래에서 볼 수 있습니다.

    from django.core.management import BaseCommand
    from beers.models import Beer
    
    class Command(BaseCommand):
        def __init__(self, *args, **kwargs):
            super(Command, self).__init__(*args, **kwargs)
    
        help = "Update Beer table from punkapi.com"
    
        def handle(self, *args, **options):
                # Implement the logic here
                pass
    
    


    이 경우 API에 데이터를 요청하면 데이터베이스에 기록됩니다. requests 라이브러리도 사용합니다.

    명령의 전체 코드는 다음과 같을 수 있습니다. (단지 데모용입니다. 실제 시나리오에서는 맥주가 이미 데이터베이스에 있는지 쿼리하기 위해 맥주 이름을 사용하지 않을 것입니다.)

    from django.core.management import BaseCommand
    
    import requests
    
    from beers.models import Beer
    
    
    class Command(BaseCommand):
        def __init__(self, *args, **kwargs):
            super(Command, self).__init__(*args, **kwargs)
    
        help = "Update Beer table from punkapi.com"
    
        def handle(self, *args, **options):
            # Request data from the beer API
            response = requests.get('https://api.punkapi.com/v2/beers/?beer_name=my_name_is')
    
            # Loop through the response
            for beer in response.json():
                try:
                    beer_row = Beer.objects.get(name=beer['name'])
                except Beer.DoesNotExist:
                    beer_row = None
    
                if beer_row:
                    # Beer already exists - do nothing
                    self.stdout.write(f'{beer_row.name} already exists.')
                    continue
                else:
                    # Add beer to db
                    self.stdout.write('Create new row')
                    beer_row = Beer()
                    beer_row.name = beer['name']
                    beer_row.tagline = beer['tagline']
                    beer_row.first_brewed = beer['first_brewed']
                    beer_row.description = beer['description']
                    beer_row.save()
    
            self.stdout.write('#########################')
            self.stdout.write('Updated Beer list')
            self.stdout.write('#########################')
    
    


    여기에서 맥주가 데이터베이스에 이미 존재하는지 확인합니다. 그렇지 않은 경우 데이터베이스에 추가합니다.

    사용자 지정 명령 실행



    다음을 실행하여 사용자 지정 명령을 실행합니다.

    python manage.py update_beers
    


    출력이 표시됩니다.


    명령 실행 결과

    모든 것이 순조롭게 진행되면 맥주에 대한 데이터에 대해 API가 요청되고 데이터가 데이터베이스에 기록됩니다.

    또 다른 방법



    API에서 기존 맥주에 대한 업데이트를 받고 싶다면 어떻게 해야 할까요?

    핸들 메소드를 이렇게 다시 작성하세요.

    def handle(self, *args, **options):
            response = requests.get('https://api.punkapi.com/v2/beers/?beer_name=my_name_is')
    
            for beer in response.json():
    
                object, created = Beer.objects.update_or_create(
                    name=beer['name'],
                    defaults={
                        'tagline': beer['tagline'],
                        'first_brewed': beer['first_brewed'],
                        'description': beer['description']
                    }
                )
    
                object.save()
    
                if created:
                    self.stdout.write('New beer added')
                else:
                    self.stdout.write(f'{beer["name"]} updated')
    


    여기서는 튜플을 반환하는 Djangos update_or_create 메서드를 사용합니다. 여기서 object는 생성되거나 업데이트된 객체이고 created는 새 객체가 생성되었는지 여부를 지정하는 부울입니다.

    결론



    이 기사에서는 Django에서 사용자 지정 manage.py 명령을 빌드하는 방법을 설명했습니다. 이 문서에서는 requests 라이브러리를 통해 API에서 데이터를 가져오고 데이터베이스에 저장하는 사용자 정의 명령을 빌드하는 방법을 보여줍니다.

    사용자 지정 명령을 예약된 작업으로 설정하려면 아래의 마지막 리소스 링크를 살펴보십시오.

    자원


  • Writing custom django-admin commands (Django documentation)
  • The full source code of this Beer app at GitHub
  • Handling Periodic Tasks in Django with Celery and Docker
  • 좋은 웹페이지 즐겨찾기