# 관리자 뷰에서 폼 사용하기 [Django의 폼 프레임워크](inv:django#topics/forms/index)는 다른 Django 앱과 마찬가지로 Wagtail 관리자 뷰 내에서 사용할 수 있습니다. 그러나 Wagtail은 날짜/시간 선택기, 페이지, 문서, 이미지 및 스니펫용 선택기와 같은 다양한 관리자별 폼 위젯도 제공합니다. `django.forms.models.ModelForm` 대신 `wagtail.admin.forms.models.WagtailAdminModelForm` 을 기본 클래스로 사용하여 폼을 구성하면 각 모델 필드에 가장 적합한 위젯이 선택됩니다. 예를 들어, 다음 모델 및 폼 정의가 주어졌을 때: ```python from django.db import models from wagtail.admin.forms.models import WagtailAdminModelForm from wagtail.images.models import Image class FeaturedImage(models.Model): date = models.DateField() image = models.ForeignKey(Image, on_delete=models.CASCADE) class FeaturedImageForm(WagtailAdminModelForm): class Meta: model = FeaturedImage ``` 폼의 `date` 및 `image` 필드는 각각 날짜 선택기 및 이미지 선택기 위젯을 사용합니다. ## 관리자 폼 위젯 정의 자신만의 폼 위젯을 구현했다면, `WagtailAdminModelForm` 이 주어진 모델 필드 유형에 대해 해당 위젯을 선택하도록 구성할 수 있습니다. 이는 일반적으로 `AppConfig.ready` 메서드에서 `wagtail.admin.forms.models.register_form_field_override` 함수를 호출하여 수행됩니다. ```{eval-rst} .. function:: register_form_field_override(model_field_class, to=None, override=None, exact_class=False) :code:`WagtailAdminModelForm` 이 주어진 모델 필드 유형을 만날 때 폼 필드의 기본값을 재정의할 옵션 세트를 지정합니다. :param model_field_class: :code:`models.CharField` 와 같은 모델 필드 클래스를 지정합니다. 재정의는 이 클래스의 인스턴스인 필드에 적용됩니다. :param to: :code:`ForeignKey` 필드의 경우, 재정의가 적용되려면 필드가 가리켜야 하는 모델을 나타냅니다. :param override: :code:`widget` 과 같이 폼 필드의 :code:`__init__` 메서드에 전달될 키워드 인수 사전입니다. :param exact_class: True인 경우, 재정의는 :code:`model_field_class` 로 주어진 정확한 유형의 모델 필드에만 적용되며, 해당 서브클래스에는 적용되지 않습니다. ``` 예를 들어, `wagtail.videos` 앱이 `Video` 모델과 `VideoChooser` 폼 위젯을 구현하는 경우, 다음 AppConfig 정의는 `WagtailAdminModelForm` 이 `Video` 를 가리키는 모든 외래 키에 대해 `VideoChooser` 를 폼 위젯으로 선택하도록 보장합니다. ```python from django.apps import AppConfig from django.db.models import ForeignKey class WagtailVideosAppConfig(AppConfig): name = 'wagtail.videos' label = 'wagtailvideos' def ready(self): from wagtail.admin.forms.models import register_form_field_override from .models import Video from .widgets import VideoChooser register_form_field_override(ForeignKey, to=Video, override={'widget': VideoChooser}) ``` Wagtail의 페이지 및 스니펫 편집 뷰는 `WagtailAdminModelForm` 을 표준으로 사용하므로, 이 변경 사항은 Wagtail 관리자 전체에 적용됩니다. 페이지 모델의 `Video` 에 대한 외래 키는 이를 명시적으로 지정할 필요 없이 자동으로 `VideoChooser` 위젯을 사용합니다. (forms_panels_overview)= ## 패널 패널(Wagtail 3.0까지는 편집 핸들러라고도 함)은 템플릿을 작성할 필요 없이 모델 폼의 내용과 레이아웃을 지정하는 Wagtail의 메커니즘입니다. 이는 페이지 및 스니펫의 편집 인터페이스와 [사이트 설정](/reference/contrib/settings) contrib 모듈에 사용됩니다. Wagtail에서 제공하는 패널 유형 세트는 [](/reference/panels)를 참조하십시오. 모든 패널은 기본 클래스 `wagtail.admin.panels.Panel` 에서 상속됩니다. 단일 패널 객체(일반적으로 `ObjectList` 또는 `TabbedInterface`)는 최상위 수준에 존재하며 뷰 코드에서 직접 액세스되는 유일한 객체입니다. 자식 패널을 포함하는 패널은 기본 클래스 `wagtail.admin.panels.PanelGroup` 에서 상속되며, 적절한 경우 자식 패널에 대한 메서드를 재귀적으로 호출하는 것을 처리합니다. 뷰는 패널 메커니즘을 통해 모델 폼을 렌더링하기 위해 다음 단계를 수행합니다. - 모델에 대한 최상위 패널 객체를 검색합니다. 일반적으로 모델의 `edit_handler` 속성을 조회하고 모델의 `panels` 속성으로 주어진 자식으로 구성된 `ObjectList` 로 대체하여 수행됩니다. 그러나 다른 곳에서 올 수도 있습니다. 예를 들어, 스니펫은 `SnippetViewSet` 클래스를 통해 패널을 정의할 수 있습니다. - `PanelsGroup` 의 권한이 사용자가 이 패널을 볼 수 있도록 허용하지 않으면 더 이상 아무것도 수행되지 않습니다. - 이는 `permission` 키워드 인수를 사용하여 수정할 수 있습니다. [](customizing_the_tabbed_interface) 및 [](panels_permissions)에서 이 사용법의 예시를 참조하십시오. - 뷰는 최상위 패널에서 `bind_to_model` 을 호출하고 모델 클래스를 전달하며, 이는 `model` 속성이 있는 패널의 복제본을 반환합니다. 이 프로세스의 일부로 각 자식 패널에서 `on_model_bound` 메서드가 호출되어 모델에 액세스해야 하는 추가 초기화를 수행할 수 있습니다(예: `FieldPanel` 이 모델 필드 정의를 검색하는 곳). - 뷰는 최상위 패널에서 `get_form_class` 를 호출하여 모델을 편집하는 데 사용할 수 있는 ModelForm 서브클래스를 검색합니다. 이는 다음과 같이 진행됩니다. - 모델의 `base_form_class` 속성에서 기본 폼 클래스를 검색하고 `wagtail.admin.forms.WagtailAdminModelForm` 으로 대체합니다. - 각 자식 패널에서 `get_form_options` 를 호출합니다(이는 `fields` 및 `widgets` 를 포함하는 속성 사전을 반환함). 결과를 단일 사전으로 병합합니다. - 내부 `Meta` 클래스의 속성을 형성하는 옵션 사전과 함께 기본 폼 클래스의 서브클래스를 구성합니다. - 일반 Django 폼 뷰에 따라 폼 클래스의 인스턴스가 생성됩니다. - 뷰는 최상위 패널에서 `get_bound_panel` 을 호출하고 `instance`, `form` 및 `request` 를 키워드 인수로 전달합니다. 이는 [템플릿 컴포넌트 API](/extending/template_components)를 따르는 `BoundPanel` 객체를 반환합니다. 마지막으로 `BoundPanel` 객체(및 해당 미디어 정의)가 템플릿에 렌더링됩니다. 새로운 패널 유형은 `wagtail.admin.panels.Panel` 을 서브클래싱하여 정의할 수 있습니다. [](panels_api)를 참조하십시오.