[Django] 이것저것

김재연·2022년 9월 16일
1

Watti

목록 보기
9/10
post-thumbnail

1. 설정

(1) 미디어 설정 + 이미지 필드 사용하기

# settings.py
# 미디어 파일이 /media/ 폴더 밑으로 등록된다.
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
# models.py
import os

# 이미지 저장 경로를 직접 지정할 수 있다.
def image_upload_path(instance, filename):
    upload_path = os.path.join(str(instance.project.user), filename)
    return upload_path
    
class Project(models.Model):
    project_name = models.CharField(max_length=50, help_text="프로젝트명")
    ...
    # admin에서 ProjectImage가 연결된 Project 객체를 project_name 필드로 보여준다.
    def __str__(self):
        return self.project_name
    
class ProjectImage(models.Model):
    project = models.OneToOneField(Project, on_delete=models.CASCADE, help_text="프로젝트")
    image = models.ImageField(upload_to=image_upload_path, help_text="이미지(썸네일)")
    created_at = models.DateTimeField(auto_now_add=True, help_text="생성날짜")
    updated_at = models.DateTimeField(auto_now=True, help_text="수정날짜")
# 이미지 필드를 사용하려면 설치해야 하는 패키지
pip install pillow
# project/urls.py
from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    path('admin/', admin.site.urls),
    ...
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
# 이미지의 url로 접속했을 때 이미지가 보이도록 하는 설정

(2) gitignore 적용시키기

이미 올려버린 파일들을 뒤늦게 gitignore에 작성했는데 이게 적용이 안되고 계속 올라갈 경우

git rm -r --cached .
git add .
git commit -m "fixed untracked files"

캐시를 다 지우고 다시 올린다.

.gitignore가 작동하지 않을때 대처법


2. admin

(1) admin에서 필드값 다 보이게 세팅하기

# admin.py
class ExampleAdmin(admin.ModelAdmin):
    list_display = [f.name for f in Example._meta.fields]

admin.site.register(Example, ExampleAdmin)

(2) admin에서 행(필드) 검색하기

장고의 admin 페이지에서 특정 필드값을 검색해서 찾고 싶을 때

# admin.py
class SampleAdmin(admin.ModelAdmin):
    list_display = ['AAA', 'BBB', 'CCC', ... ]
    search_fields = ['AAA', 'BBB', 'CCC', ...] # 추가

admin.site.register(Sample, SampleAdmin)

맨 위에 검색창이 생긴다. search_fields에 쓴 모든 필드가 검색 범위에 포함된다.


3. 데이터베이스

(1) 마이그레이션 초기화

  1. find . -path "*/migrations/*.py" -not -name "__init__.py" -delete
  2. find . -path "*/migrations/*.pyc" -delete
  3. 데이터베이스 삭제 후 재생성
    • DROP DATABASE 데이터베이스명;
    • CREATE DATABASE 데이터베이스명;
    • (GRANT ALL PRIVILEGES ON DATABASE 데이터베이스명 To 유저;)
  4. python manage.py makemigrations
  5. python manage.py migrate

[Django] Django 마이그레이션 초기화하기

(2) 데이터베이스 연결 세션 종료하기

  1. postgres=# select pg_terminate_backend(pid)
  2. postgres-# from pg_stat_activity
  3. postgres-# where datname = '데이터베이스명';

[에러노트] database ‘template1’ is being accessed by other users. DETAIL: There are 1 other session(s) using the database.

(3) dumpdata & loaddata

데이터베이스에 저장된 정보들을 json으로 저장

python manage.py dumpdata 앱이름.모델이름 > 파일명.json

이 모델에 저장돼있던 데이터들이

이렇게 뽑혀나온다

위에서 뽑은 json 데이터들을 데이터베이스에 저장

python manage.py loaddata 파일명.json

다시 이렇게 데이터베이스에 저장됨

(4) bulk_update

예전에 데이터베이스에 한번에 저장하는 방식으로 bulk_create에 대한 포스팅을 한 적이 있는데 이번에는 bulk_update다. 전에도 한번 써보면서 내가 업데이트할 객체를 어떻게 지정해서 한번에 저장하는건지 긴가민가했는데 이번에 정리가 됐다.

# 1. 업데이트할 객체들을 불러오고
sample = Sample.objects.all()

# 2. 하나하나 접근해서 값 변경하고
for s in sample:
	s.field_name1 = VALUE1
    s.field_name2 = VALUE2

# 3. 마지막에 한번에 업데이트
Sample.objects.bulk_update(sample, ['field_name1', 'field_name2'])

bulk_update의 첫번째 변수는 영향을 받을 쿼리셋, 두번째 변수는 영향 받는 컬럼(필드명)이다.

❗ 영향을 받을 쿼리셋이기 때문에 객체들을 불러올때는 filter()를 이용해서 불러와야한다.


4. M:N

(1) ManytoManyField admin에서 보기

manytomanyfieldlist_display로 안보여서 따로 뭔가 해줘야됨.

# models.py
class SampleModel(models.Model):
    ...
    sample = models.ManyToManyField("FK_sample", related_name="sample", help_text="샘플")

    def display_sample(self):
        return ', '.join(sample.name for sample in self.sample.all())

    display_sample.short_description = 'Sample'
# admin.py
class SampleModelAdmin(admin.ModelAdmin):
    list_display = [f.name for f in SampleModel._meta.fields] + ["display_sample"]
    
admin.site.register(SampleModel, SampleModelAdmin)

Django Tutorial Part 4: Django admin site

(2) ManyToManyField 데이터 보내기

{
    "project":1,
    "purpose":["00001", "00002"],
    "structure":["00001", "00003"]
}

PK를 리스트로 보낸다.

admin에서 이렇게 뜬다. 근데 목차 페이지에는 아예 안떠서 찾아보니 ManyToManyField는 거대한 데이터베이스 접근 비용이 발생할 수 있기 때문에 장고가 이것을 방지해서 list_display에 직접적으로 특정할 수 없다고 한다.

(3) 객체 데이터 여러개 보내기

{
    "datalayer_name":"데이터레이어1",
    "colorsetting":[
        {"min":0, "max":10, "color":[255,0,0], "order":1},
        {"min":11, "max":20, "color":[0,255,0], "order":2},
        {"min":21, "max":30, "color":[0,0,255], "order":3}
    ]
}

[] 안에 객체 데이터 하나씩 {}로 묶어서 여러개 보내기 (개수제한X)

colorsettings = []
if data.get('colorsetting'):
	for c in data.get('colorsetting'):
		colorsettings.append(
			ColorSetting(
				datalayer=datalayer,
				min=c.get('min'),
				max=c.get('max'),
				target=c.get('target'),
				color=c.get('color'),
				order=c.get('order'),
			)
		)
ColorSetting.objects.bulk_create(colorsettings)

for문으로 돌려서 하나씩 접근

profile
일기장같은 공부기록📝

0개의 댓글