관리 메뉴

Leo's Garage

Django #5 Users App custom -2 본문

Study/Django

Django #5 Users App custom -2

LeoBehindK 2023. 1. 2. 10:28
728x90
반응형

이전 포스팅에서 이어서 Users App을 수정하도록 하겠다. 

이전 포스팅에서 아래와 같은 에러 메시지를 보았다. 

이 말은 user의 데이터 구조는 변경하였는데, admin 패널에 페이지는 기존의 user app의 admin 패널을 그대로 상속했기 때문에 문제가 된다는 것을 알려주는 것이다. 

즉 우리는 first name과 last name을 데이터에서 받지 않는데 admin 패널에서는 그것들을 찾고 있는 상황이다. 

자 그러면 users의 admin.py의 코드를 살펴보자

from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from .models import User

# Register your models here.
@admin.register(User)
class CustomUserAdmin(UserAdmin):
    pass

여기서 UserAdmin의 선언부를 찾아서 들어가 보자

@admin.register(User)
class UserAdmin(admin.ModelAdmin):
    add_form_template = "admin/auth/user/add_form.html"
    change_user_password_template = None
    fieldsets = (
        (None, {"fields": ("username", "password")}),
        (_("Personal info"), {"fields": ("first_name", "last_name", "email")}),
        (
            _("Permissions"),
            {
                "fields": (
                    "is_active",
                    "is_staff",
                    "is_superuser",
                    "groups",
                    "user_permissions",
                ),
            },
        ),
        (_("Important dates"), {"fields": ("last_login", "date_joined")}),
    )

기존 users admin을 살펴보면, fieldses라는 것이 보인다.

이것이 바로 admin 페이지 내에 보여지는 각 field들을 설정한 코드이다.

위에서 보다 시피, 기존의 users app에는 first name, last name, email등이 들어가고, Permissions 부분에는 각 user 계정들이 가지는 속성들이 나열되어 있다.

이를 참조해서 우리 user app의 admin 코드를 수정해보자

from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from .models import User

# Register your models here.
@admin.register(User)
class CustomUserAdmin(UserAdmin):
    fieldsets = (
        (
            "Profile",
            {"fields": ("username", "password", "name", "email", "is_host"),
             "classes" :("wide",),
             },
        ),
        (
            "Permission",
            {
                "fields": (
                    "is_active",
                    "is_staff",
                    "is_superuser",
                    "groups",
                    "user_permissions",
                ),
                "classes":("collapse",),
            },
        ),
        (
            "Important Dates", {
                "fields": (
                    "last_login", "date_joined"
                ),
                "classes":("collapse",),
            }
        ),
    )
    list_display = ("username", "email", "name", "is_host")

우선 우리가 없는 first name과 last name은 없애고, username과 is_host를 추가하였다. 

Important Date는 각 user들의 정보와 관련된 filed이다. 

각 field에 추가된 classes라는 property의 경우에는 각 field가 어떻게 보여지는지에 대한 설정이다. 

이제 화면을 Reload하면

위와 같이 admin 페이지가 정상적으로 나오는 것을 알 수 있다. 

자 이번에는 model, 즉 app들의 데이터 간에 관계에 대해 정의해보자 

예를 들어 houses에 들어있는 house 데이터들의 owner가 지정되어야 할 것이다.

owner는 users 데이터에 user 들 중 하나가 되어야 할 것이다.

 

이런 연결을 하기 위해 사용되는 개념은 ID 혹은 Primary Key이다.

그러나 우리는 이런 값을 model에서 선언한 적이 없다. 

하지만 Django는 이러한 값을 자동으로 생성해준다. 

예를 들어 houses에 신규 house를 하나 생성해보자

이렇게 신규 house를 생성하고 저장하면,

해당 데이터를 클릭했을 때 url에 1이라는 숫자가 표기된 것이 보일 것이다.

이것이 바로 ID이다. 

이 ID를 통해서 데이터와 데이터를 연결할 수 있다. 

자 우선 이것을 하기 전에 특정 app의 model.py를 수정해야 한다. 

houses 폴더 내에 model.py를 아래와 같이 작성해보자

from django.db import models

# Create your models here.
class House(models.Model):
    
    """Model Definition for House"""
    name = models.CharField(max_length=140)
    price_per_night = models.PositiveIntegerField(verbose_name="Price", help_text="Positive Numbers Only")
    description = models.TextField()
    address = models.CharField(max_length=140)
    pets_allowed = models.BooleanField(
        verbose_name="Pets Allowed?",
        default=True, help_text="Does this house allow pets?")
    
    owner = models.ForeignKey("users.User", on_delete=models.CASCADE)

    def __str__(self):
        return self.name

여기서 추가된 부분은 owner 부분이다. 

ForeignKey는 ID를 받는다. 

따라서 해당 코드를 해석해보면, users.User 데이터의 ID를 받는다는 뜻이고, on_delete는 ForeignKey 설정 시, 필수로 들어가야 하는 옵션인데, 즉 해당 ID를 가진 데이터가 삭제되었을 때 현재 데이터의 처리방법에 대한 이야기이다.

models.CASCADE는 함께 삭제하라는 뜻이다.

 

자 이제 이렇게 코드를 수정하고 나서 돌려보도록 하자. 

기존에 생성된 데이터들과 충돌이 날 수 있으니 각 app의 migrations 폴더 내에 initial.py를 삭제해 주고, db.sqlite3도 삭제해준다. 

python manage.py makemigrations
python manage.py migrate
python manage.py createsuperuser
python manage.py runserver

위의 명령어를 순차적으로 수행한 뒤에 houses의 데이터를 새로 만들어보자.

위와 같은 화면이 나오게 된다. 

살펴보면 데이터 생성 화면에 owner가 있는 것이 보인다. 

이 owner 항목을 통해서 해당 house 데이터의 owner를 누구로 할 것인지 지정할 수 있다. 

 

728x90
반응형

'Study > Django' 카테고리의 다른 글

Django #6 Make models more - 1  (0) 2023.01.02
Django #4 Users App custom -1  (0) 2022.12.30
Django #3 admin 기능 추가해보기  (0) 2022.12.28
Django #2 app 만들기  (0) 2022.12.28
Django #1 프로젝트 셋업 및 기본 동작 확인  (0) 2022.12.27
Comments