# 설정 `wagtail.contrib.settings` 모듈을 사용하면 모든 사이트 레코드에 공통적이거나 각 사이트에 특정한 설정을 포함하는 모델을 정의할 수 있습니다. 설정은 Wagtail 관리자에서 관리자가 편집할 수 있으며 코드와 템플릿 모두에서 액세스할 수 있습니다. ## 설치 `INSTALLED_APPS` 에 `wagtail.contrib.settings` 를 추가합니다. ```python INSTALLED_APPS += [ 'wagtail.contrib.settings', ] ``` **참고:** 템플릿 내에서 `settings` 를 사용하는 경우 `TEMPLATES` 설정도 업데이트해야 합니다(이 페이지 뒷부분에서 설명). ## 설정 정의 다음 중 하나를 상속하는 모델을 만듭니다. - 모든 사이트에 공통적인 일반 설정의 경우 `BaseGenericSetting` - 사이트별 설정의 경우 `BaseSiteSetting` 그리고 `register_setting` 데코레이터를 사용하여 등록합니다. ```python from django.db import models from wagtail.contrib.settings.models import ( BaseGenericSetting, BaseSiteSetting, register_setting, ) @register_setting class GenericSocialMediaSettings(BaseGenericSetting): facebook = models.URLField() @register_setting class SiteSpecificSocialMediaSettings(BaseSiteSetting): facebook = models.URLField() ``` 설정 링크는 Wagtail 관리자 '설정' 메뉴에 나타납니다. (edit_handlers_settings)= ## 편집 핸들러 설정은 Wagtail의 나머지 부분과 마찬가지로 편집 핸들러를 사용합니다. 모든 필수 편집 핸들러를 정의하는 `panels` 설정을 모델에 추가합니다. ```python @register_setting class GenericImportantPages(BaseGenericSetting): donate_page = models.ForeignKey( 'wagtailcore.Page', null=True, on_delete=models.SET_NULL, related_name='+' ) sign_up_page = models.ForeignKey( 'wagtailcore.Page', null=True, on_delete=models.SET_NULL, related_name='+' ) panels = [ FieldPanel('donate_page'), FieldPanel('sign_up_page'), ] @register_setting class SiteSpecificImportantPages(BaseSiteSetting): donate_page = models.ForeignKey( 'wagtailcore.Page', null=True, on_delete=models.SET_NULL, related_name='+' ) sign_up_page = models.ForeignKey( 'wagtailcore.Page', null=True, on_delete=models.SET_NULL, related_name='+' ) panels = [ FieldPanel('donate_page'), FieldPanel('sign_up_page'), ] ``` 사용자 지정 `edit_handler` 속성을 사용하여 [페이지 모델과 마찬가지로](customizing_the_tabbed_interface) 편집 핸들러를 사용자 지정할 수도 있습니다. ```python from wagtail.admin.panels import TabbedInterface, ObjectList @register_setting class MySettings(BaseGenericSetting): # ... first_tab_panels = [ FieldPanel('field_1'), ] second_tab_panels = [ FieldPanel('field_2'), ] edit_handler = TabbedInterface([ ObjectList(first_tab_panels, heading='첫 번째 탭'), ObjectList(second_tab_panels, heading='두 번째 탭'), ]) ``` ## 권한 설정은 슈퍼유저와 설정 모델에 대한 "변경" 권한이 부여된 모든 사용자가 편집할 수 있습니다. 또한 `BaseSiteSetting` 을 확장하는 모델의 경우 관리자의 그룹 영역에서 설정 아래의 개별 사이트에 대한 권한을 할당할 수 있습니다. ```{versionadded} 7.1 개별 사이트에 대한 권한을 할당하는 기능이 추가되었습니다. ``` ## 모양 모델의 `verbose_name` 을 변경하여 메뉴에 사용되는 레이블을 변경할 수 있습니다. `register_setting` 데코레이터에 `icon` 인수를 전달하여 메뉴에 아이콘을 추가할 수 있습니다. ```python @register_setting(icon='placeholder') class GenericSocialMediaSettings(BaseGenericSetting): ... class Meta: verbose_name = "모든 사이트의 소셜 미디어 설정" @register_setting(icon='placeholder') class SiteSpecificSocialMediaSettings(BaseSiteSetting): ... class Meta: verbose_name = "사이트별 소셜 미디어 설정" ``` Wagtail의 기본 아이콘 세트는 [아이콘 개요](icons)에서 볼 수 있습니다. 주어진 프로젝트에서 사용 가능한 모든 아이콘은 [스타일 가이드](styleguide)에 표시됩니다. ## 설정 사용 설정은 Python 코드와 템플릿 모두에서 사용할 수 있습니다. ### Python에서 사용 #### 일반 설정 뷰에서 일반 설정에 액세스해야 하는 경우 `BaseGenericSetting.load()` 메서드를 사용하여 일반 설정을 검색할 수 있습니다. ```python def view(request): social_media_settings = GenericSocialMediaSettings.load(request_or_site=request) ... ``` `request_or_site` 인수는 선택 사항입니다. 이 인수가 전달되고 요청 객체인 경우, 동일한 요청 내에서 반복되는 데이터베이스 조회를 피하기 위해 결과가 요청에 캐시됩니다. (site_settings)= #### 사이트별 설정 뷰에서 사이트별 설정에 액세스해야 하는 경우 `BaseSiteSetting.for_request()` 메서드를 사용하여 현재 요청에 대한 사이트별 설정을 검색할 수 있습니다. ```python def view(request): social_media_settings = SiteSpecificSocialMediaSettings.for_request(request=request) ... ``` 요청을 사용할 수 없지만 설정을 검색하려는 `Site` 를 아는 경우 대신 `BaseSiteSetting.for_site` 를 사용할 수 있습니다. ```python def view(request): social_media_settings = SiteSpecificSocialMediaSettings.for_site(site=user.origin_site) ... ``` ### Django 템플릿에서 사용 `wagtail.contrib.settings.context_processors.settings` 컨텍스트 프로세서를 설정에 추가합니다. ```python TEMPLATES = [ { ... 'OPTIONS': { 'context_processors': [ ... 'wagtail.contrib.settings.context_processors.settings', ] } } ] ``` 그런 다음 `{{ settings }}` 를 통해 일반 설정에 액세스합니다. ```html+django {{ settings.app_label.GenericSocialMediaSettings.facebook }} {{ settings.app_label.SiteSpecificSocialMediaSettings.facebook }} ``` **참고:** `app_label` 을 설정 모델이 포함된 앱의 레이블로 바꿉니다. `RequestContext` 에 있지 않은 경우 컨텍스트 프로세서가 실행되지 않으며 `settings` 변수를 사용할 수 없습니다. `settings` 를 얻으려면 제공된 `{% get_settings %}` 템플릿 태그를 사용하십시오. ```html+django {% load wagtailsettings_tags %} {% get_settings %} {{ settings.app_label.GenericSocialMediaSettings.facebook }} {{ settings.app_label.SiteSpecificSocialMediaSettings.facebook }} ``` 기본적으로 태그는 컨텍스트에 `settings` 변수를 만들거나 업데이트합니다. 대신 다른 컨텍스트 변수에 할당하려면 `{% get_settings as other_variable_name %}` 를 사용하십시오. ```html+django {% load wagtailsettings_tags %} {% get_settings as wagtail_settings %} {{ wagtail_settings.app_label.GenericSocialMediaSettings.facebook }} {{ wagtail_settings.app_label.SiteSpecificSocialMediaSettings.facebook }} ``` ### Jinja2 템플릿에서 사용 `wagtail.contrib.settings.jinja2tags.settings` 확장을 Jinja2 설정에 추가합니다. ```python TEMPLATES = [ ... { 'BACKEND': 'django.template.backends.jinja2.Jinja2', 'APP_DIRS': True, 'OPTIONS': { 'extensions': [ ... 'wagtail.contrib.settings.jinja2tags.settings', ], }, } ] ``` 그런 다음 `settings()` 템플릿 함수를 통해 설정에 액세스합니다. ```html+jinja {{ settings("app_label.GenericSocialMediaSettings").facebook }} {{ settings("app_label.SiteSpecificSocialMediaSettings").facebook }} ``` **참고:** `app_label` 을 설정 모델이 포함된 앱의 레이블로 바꿉니다. 템플릿에 `request` 를 사용할 수 없는 경우 대신 기본 사이트의 설정을 사용할 수 있습니다. ```html+jinja {{ settings("app_label.GenericSocialMediaSettings", use_default_site=True).facebook }} {{ settings("app_label.SiteSpecificSocialMediaSettings", use_default_site=True).facebook }} ``` **참고:** 요청 객체를 사용할 수 없는 경우 이 템플릿 태그에서 현재 사이트에 대한 올바른 설정 인스턴스를 안정적으로 가져올 수 없습니다. 이는 Wagtail의 다중 사이트 인스턴스에만 해당됩니다. 입력을 줄이기 위해 설정 인스턴스를 변수에 저장할 수 있습니다. 하나의 모델에서 여러 값을 사용해야 하는 경우: ```html+jinja {% with generic_social_settings=settings("app_label.GenericSocialMediaSettings") %} Facebook에서 {{ generic_social_settings.facebook }}으로 팔로우하거나, Instagram에서 @{{ generic_social_settings.instagram }}으로 팔로우하세요. {% endwith %} {% with site_social_settings=settings("app_label.SiteSpecificSocialMediaSettings") %} Facebook에서 {{ site_social_settings.facebook }}으로 팔로우하거나, Instagram에서 {{ site_social_settings.instagram }}으로 팔로우하세요. {% endwith %} ``` 또는 `set` 태그를 사용하여: ```html+jinja {% set generic_social_settings=settings("app_label.GenericSocialMediaSettings") %} {% set site_social_settings=settings("app_label.SiteSpecificSocialMediaSettings") %} ``` ## 효율성 향상을 위한 `select_related` 활용 다른 객체(예: 페이지)에 대한 외래 키 관계가 있는 모델의 경우, 템플릿에서 값을 출력하는 데 매우 자주 필요합니다. 모델에 `select_related` 속성을 설정하여 Wagtail이 Django의 [`QuerySet.select_related()`](django.db.models.query.QuerySet.select_related) 메서드를 활용하여 단일 쿼리로 설정 객체 및 관련 객체를 가져오도록 할 수 있습니다. 이렇게 하면 초기 쿼리가 더 복잡해지지만, 추가 쿼리 없이 외래 키 값에 자유롭게 액세스할 수 있어 전반적으로 효율성이 향상됩니다. 이전 섹션의 `GenericImportantPages` 예제를 바탕으로, 다음은 효율성을 향상시키기 위해 `select_related` 를 설정하는 방법을 보여줍니다. ```python @register_setting class GenericImportantPages(BaseGenericSetting): # GenericImportantPages 또는 사이트를 조회할 때 이 페이지를 가져옵니다. select_related = ["donate_page", "sign_up_page"] donate_page = models.ForeignKey( 'wagtailcore.Page', null=True, on_delete=models.SET_NULL, related_name='+' ) sign_up_page = models.ForeignKey( 'wagtailcore.Page', null=True, on_delete=models.SET_NULL, related_name='+' ) panels = [ FieldPanel('donate_page'), FieldPanel('sign_up_page'), ] ``` 이러한 추가 사항으로 다음 템플릿 코드는 이제 세 개의 데이터베이스 쿼리(설정을 가져오는 쿼리 하나, 각 페이지를 가져오는 쿼리 두 개) 대신 단일 데이터베이스 쿼리를 트리거합니다. ```html+django {% load wagtailcore_tags %} {% pageurl settings.app_label.GenericImportantPages.donate_page %} {% pageurl settings.app_label.GenericImportantPages.sign_up_page %} ``` ## `page_url` 설정 단축키 활용 이전 섹션과 마찬가지로 설정 모델이 페이지를 참조하고 프로젝트에서 해당 페이지의 URL을 자주 출력해야 하는 경우, 설정 모델의 `page_url` 단축키를 사용하여 더 깔끔하게 수행할 수 있습니다. 예를 들어, 다음을 수행하는 대신: ```html+django {% load wagtailcore_tags %} {% pageurl settings.app_label.GenericImportantPages.donate_page %} {% pageurl settings.app_label.GenericImportantPages.sign_up_page %} ``` 다음과 같이 작성할 수 있습니다. ```html+django {{ settings.app_label.GenericImportantPages.page_url.donate_page }} {{ settings.app_label.GenericImportantPages.page_url.sign_up_page }} ``` `page_url` 단축키를 사용하는 것은 태그를 사용하는 것보다 몇 가지 장점이 있습니다. 1. URL을 생성하기 위해 '특정' 페이지가 자동으로 가져와지므로, 직접 이 작업을 수행하거나(또는 잊어버리는) 걱정할 필요가 없습니다. 2. 결과가 캐시되므로 동일한 페이지 URL에 액세스해야 하는 경우 (예: 폼과 바닥글 탐색에서) `page_url` 단축키를 사용하는 것이 더 효율적입니다. 3. 더 간결하며, 템플릿이나 뷰(또는 다른 Python 코드)에서 사용할 때 구문이 동일하므로 더 일관된 코드를 작성할 수 있습니다. `page_url` 단축키를 사용할 때 몇 가지 유의할 점이 있습니다. 1. 단축키에 적용되는 제한 사항은 `{% pageurl %}` 태그에도 적용됩니다. 현재 요청을 사용할 수 없는 템플릿 컨텍스트에서 설정에 액세스하는 경우, 반환되는 모든 URL에는 사이트의 스키마/도메인이 포함되며, URL 생성은 그다지 효율적이지 않습니다. 2. 뷰 또는 다른 Python 코드에서 단축키를 사용하는 경우, `page_url` 에서 요청하는 속성이 설정 객체의 속성이 아니면 `AttributeError` 가 발생합니다. 3. 설정 객체에 해당 속성이 있지만 속성이 `None` 값(또는 `Page` 가 아닌 다른 값)을 반환하는 경우, 단축키는 빈 문자열을 반환합니다.