ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 장고 Models를 활용한 데이터베이스 처리
    카테고리 없음 2021. 10. 19. 15:43

    <새로운 app을 만들때 꼭 해야할 것>

    python manage.py startapp <앱이름>

    <앱이름>/url.py /  추가 => urlpatterns = [ ]

    <프로젝트명>/ settings.py /  INSTALLEDAPPS 에 새로운 <앱이름> 추가

    <프로젝트명>/ urls.py / 에 새로운 경로 추가 

     

    <부트스트랩 사용방법>

    부트스트랩의 홈페이지에서 부트스트랩 css를 html에 추가.

     

    <장고 모델(ORM) 소개>

    데이터베이스의 종류

    RDBMS: MySQL, 

    NoSQL : MongoDB

    ## Query: 데이터 베이스에 정보를 요청하는 것. SQL: DB에 쓰이는 언어. 

     

    ORM(Object-Relation Mapping):

    객체와 데이터베이스를 연결해주는 것을 의미. 즉, 장고에서 CRUD를 SQL을 사용하지 않고도 가능하다. 단, RDB만을 지원한다.

    ex) MySQL 

     

    <Django Model>

    데이터베이스 테이블과 파이썬 클래스(models.py)를 1대1로 매핑

    모델 클래스명은 단수형으로 지정. 첫문자는 대문자로. ex) Posts(x), Post(o)

    매핑되는 모델 클래스는 DB 테이블 필드 내역이 일치해야 합니다.

    모델을 만들기 전에, 서비스에 맞게 데이터베이스 설계가 필수

     

    <model 활용 순서>

    1. 모델 클래스 작성 

    2. 모델 클래스로부터 migrations 파일 생성 -> python manage.py makemigrations <앱이름>

    3. migration file을 데이터베이스에 적용 -> python manage.py migrate <앱이름> 

    4. 모델 활용 

     

    <장고의 모델 필드>

    기본 지원되는 모델필드 타입

    Primary Key : AutoField, BigAutoField

    문자열: CharField, TextField, SlugField

    날짜/시간: DateField, TimeField, DateTimeField, DurationField

    참/거짓: BooleanField, NullBooleanField

    숫자: IntegerField, SmallIntegerField, PositiveIntegerField 등등...

    파일: FileField, ImageField, FielePathField

    이메일: EmailField

    URL: URLField

    아이피: GenericlPAddressField

     

    ## TextField와 CharField의 차이는? 

    => 최대 길이 명시가 필요한 타입: Char, 그 외: Text

    => 보통은 Char를 사용해서 max_length를 표시하는 것이 좋은듯함.

     

    <자주 사용하는 model들 정리>

    => BaseModel로 정의를 해서 다른 model을 만들 때, models.Model로  받는게 아닌, BaseModel로 받을 수 있다. 

    class BaseModel(models.Model):
        created_at = models.DateTimeField(auto_now_add=True)
        updated_at = models.DateTimeField(auto_now=True)
    
        # 실제로 지정되지는 않는다.
        class Meta:
            abstract = True
    
    # author와 like_user_set의 related_name의 값이 동일해서 그냥 migrations을 하게 되면 error 발생
    # 서로 다른 related_name을 만들어 주면 된다.
    # related_name은 기본 setting으로는 class명_set 으로 설정된다. ex) related_name = post_set
    # Post.objects.filter(author=user)  ==  user.post_set.all()
    
    
    class Post(BaseModel):
        author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='my_post_set')
        photo = models.ImageField(upload_to="instagram/post/%Y/%m/%d")
        caption = models.CharField(max_length=100, blank=True)
        tag_set = models.ManyToManyField('Tag', blank=True)
        location = models.CharField(max_length=100)

    <django admin을 통한 데이터 관리>

    모델 클래스를 admin에 등록하기: 새로운 app을 만들고 나서, app의 admin.py에 입력을 해주어야 새로 만든 app이 admin 페이지에서 볼 수 있다. 

     

    admin.py

    @admin.register(Post)
    class PostAdmin(admin.ModelAdmin):
        pass

     

    <admin 안에도 다양한 속성>

    list_display = ['pk', 'name', 'short_desc', 'price', 'is_publish'] 

    이외에도 list_display_links , list_filter, search_fields 등등 있다. 

     

    <장고가 media 파일을 다루는 방법>

    Static 파일: 개발 리소스로서의 정적인 파일 (js, css, image)

    Media 파일: FileField/ ImageField를 통해 저장된 모든 파일

     

    기본 settings.py 

    MEDIA_URL = '/media/'

    MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

     

    그리고, 개발 환경의 urls에서 

    if settings.DEBUG:

       urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

     

    <모델을 통한 조회 >

    ModelCls.objects.all()

    ModelCls.objects.all().order_by('-id')[:10]

    ModelCls.objects.all().create(title="New Title")

     

    <Queryset의 정렬 및 범위 조건>

    정렬 조건을 추가하지 않으면 일관된 순서를 보장받을 수 없다. 

    class Meta: 

       ordering = ['id']

    역순으로 하고 싶다면, ordering = ['-id']

     

    <django-debug-toolbar를 통한 SQL 디버깅>

    1. terminal에서 pip install django-debug-toolbar

    2. settings.py 에서 INSTALLED_APPS, MIDDLEWARE, INTERNER_IPS 추가

    3. urls.py에서 ulrpatterns에 새로운 path 추가 

    ##debug-toolbar는 html에서 <body>가 있어야만 사용할 수 있다. debug-toolbar 기본 위치가 <body 이기 때문!>

     

    <관계를 표현하는 모델 필드 (ForeignKey)>

    1:N 관계 -> models.ForeignKey (to, on_delete)

    = 1명의 user가 쓰는 다수의 posting, comment

    = 1개의 post에 다수의 comment

     

    ForeignKey (to, on_delete)

    to: 클래스를 직접 지정, 또는 self 

    on_delete: CASCADE, SET_NULL 등등..(아래에서 확인)

    limit_choices_to: 선택사항에서 제한을 둘 수 있다. ex) 공개여부만 되어있는 것들만 선택할 수 있다. 

     

    <예시> author = models.ForeignKey(Post, on_delete=models.CASCADE)

     

    <Model의 ForeignKey on_delete 종류>

    ForeignKeyField가 값이 삭제될 때,

    1. CASCADE :  ForeignKeyField를 포함하는 모델 인스턴스도 삭제된다. 

    2. PROTECT : 삭제가 되지 않도록 ProtectedError발생

    3. SET_NULL: ForeignKeyField값을 null로 바꾼다. (null=True 추가 필수)

    4. SET_DEFAULT : ForeignKeyField값을 default로 바꾼다 (default값 필수)

    5. SET() : ForeignKeyField값을 설정된 set 함수로 바꾼다

    6. DO_NOTHING : 아무런 행동도 취하지 않는다. 조금 위험s...

     

    <관계를 표현하는 모델 필드 (OneToOneField)>

    1:1 관계 -> models.OneToOneField(to, on_delete)

    = 1명의 user는 1개의 프로필

     

    python manage.py shell 

     In [1]: from django.contrib.auth import get_user_model
     In [2]: User = get_user_model()
     In [3]: user = User.objects.first()

     In [4]: user.profile

     

    <예시> author = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)

     

    <관계를 표현하는 모델 필드 (ManyToManyField)>

    M:N 관계 -> models.ManyToManyField(to, blank=Flase)로 표현

    = 1개의 post에는 다수의 tag

     

    <예시> tag_set = models.ManyToManyField('Tag', blank=True)

     

    <마이그레이션을 통한 데이터베이스스키마 관리>

    1. 마이그레이션 파일 생성

      shell> python manage.py makemigrations <앱이름>

    2. 지정 마이그레이션 SQL 내역 출력 

      shell> python manage.py sqlmigrate <앱이름> <마이그레이션-이름>

    => 어쩔 때 사용하나요? : migration file 5번까지 저장되어 있을 때, 3번까지만 저장하고 다시 4번 부터 새로하고 싶을 때. 마이그레이션-이름을 3번으로 적용한다. 여기서 마이그레이션-이름은 0001_initial.py에서 0001_initial 까지 중 구분할 수 있는 부분까지만 쳐도 인식을 할 수 있다. 

    3. 마이그레이션 적용 현황 출력  

    shell> python manage.py showmigrations <앱이름>

    4. 지정 데이터베이스에 마이그레이션 적용

    shell> python manage.py migrate <앱이름>

     

    ++ python manage.py migrate <앱이름> zero: 저장된 모든 migration 파일들을 취소할 수 있다. 

     

    <제일 처음에 DB(sqlite)를 생성되는 시기>

    django-admin startproject 문서이름

    python manage.py migrate 

    python manage.py createsuperuser    => 이후 ls로 확인해보면 sql이 생긴 것을 확인할 수 있다. 

     

    <Migration 파일>

    데이터베이스에 어떤 변화를 가하는 Operation들을 나열 

    단, 같은 Migration 파일이라고 할지라도, DB종류에 따라 다른 SQL이 생성된다. 

    또한, DB에 저장됐다고, 이전의 migration 파일을 지우면 안된다!

    migration 파일이 너무 많아진다면,squashmigrations 명령으로 다수의 migration 파일을 통합할 수 있다. 

     

    새로운 필드가 필수필드라면? 

    makemigrations 명령을 수행할 때, 기존 Record들에 어떤 값을 채워넣을 지 묻습니다. 

    1) 지금 그 값을 입력하겠다 

    2) 명령 수행을 중단. 

     

    ## migrations 파일을 1,2,3까지 만들고, 4,5,6 을 추가적으로 만들었다. 이때 각각을 따로 migrate 하기 보다는, migration의 위치를 3으로 옮기고, 4,5,6 파일을 지우고, 한번에 migrate를 하자. 그러면 4,5,6 이 한번에 합쳐진 migration파일을 만들 수 있다. 

     

     

     

     

Designed by Tistory.