[python] 사용자 정의 양식에서 Django 시간 / 날짜 위젯 사용

기본 관리자가 사용자 정의보기와 함께 사용하는 멋진 JavaScript 날짜 및 시간 위젯을 사용하려면 어떻게해야합니까?

Django forms documentation 을 살펴 보았고 django.contrib.admin.widgets에 대해 간략하게 언급했지만 사용법을 모르겠습니다.

여기에 적용하려는 템플릿이 있습니다.

<form action="." method="POST">
    <table>
        {% for f in form %}
           <tr> <td> {{ f.name }}</td> <td>{{ f }}</td> </tr>
        {% endfor %}
    </table>
    <input type="submit" name="submit" value="Add Product">
</form>

또한, 나는이 양식에 대한 견해를 실제로 작성하지 않았으며 일반적인 견해를 사용하고 있음에 유의해야한다고 생각합니다. 다음은 url.py의 항목입니다.

(r'^admin/products/add/$', create_object, {'model': Product, 'post_save_redirect': ''}),

그리고 나는 장고 / MVC / MTV 전체에 대해 새롭기 때문에 쉽게 가십시오 …



답변

시간이 지남에 따라이 답변의 복잡성이 증가하고 많은 해킹이 필요하므로 아마도이 작업을 수행하지 않도록주의해야합니다. 그것은 문서화되지 않은 관리자의 내부 구현 세부 사항에 의존하고 있으며 장고의 장래 버전에서 다시 깨질 가능성이 있으며 다른 JS 달력 위젯을 찾아서 사용하는 것보다 구현하기가 쉽지 않습니다.

즉,이 작업을 수행하기로 결정한 경우 다음을 수행해야합니다.

  1. 모델에 대한 고유 한 ModelForm 서브 클래스를 정의하고 (앱에 forms.py에 넣는 것이 가장 좋습니다) AdminDateWidget / AdminTimeWidget / AdminSplitDateTime을 사용하도록 지시하십시오 ( ‘mydate’등을 모델의 적절한 필드 이름으로 바꾸십시오).

    from django import forms
    from my_app.models import Product
    from django.contrib.admin import widgets
    
    class ProductForm(forms.ModelForm):
        class Meta:
            model = Product
        def __init__(self, *args, **kwargs):
            super(ProductForm, self).__init__(*args, **kwargs)
            self.fields['mydate'].widget = widgets.AdminDateWidget()
            self.fields['mytime'].widget = widgets.AdminTimeWidget()
            self.fields['mydatetime'].widget = widgets.AdminSplitDateTime()
  2. URLconf를 ‘form_class’: ‘model’대신 ProductForm : Product를 일반 create_object보기로 전달하도록 변경하십시오 (물론 “my_app.models import Product”대신 “my_app.forms import ProductForm”을 의미 함).

  3. 템플리트 헤드에 {{form.media}}를 포함시켜 Javascript 파일에 대한 링크를 출력하십시오.

  4. 그리고 해키 부분 : 관리 날짜 / 시간 위젯은 i18n JS 항목이로드되었으며 core.js가 필요하지만 자동으로 하나를 제공하지는 않는다고 가정합니다. 따라서 {{form.media}} 위의 템플릿에는 다음이 필요합니다.

    <script type="text/javascript" src="/my_admin/jsi18n/"></script>
    <script type="text/javascript" src="/media/admin/js/core.js"></script>

    Alex 에게 다음과 같은 관리자 CSS를 사용할 수도 있습니다 .

    <link rel="stylesheet" type="text/css" href="/media/admin/css/forms.css"/>
    <link rel="stylesheet" type="text/css" href="/media/admin/css/base.css"/>
    <link rel="stylesheet" type="text/css" href="/media/admin/css/global.css"/>
    <link rel="stylesheet" type="text/css" href="/media/admin/css/widgets.css"/>

이는 Django의 관리 미디어 (ADMIN_MEDIA_PREFIX)가 / media / admin /에 있음을 의미합니다. 설정에 맞게 변경할 수 있습니다. 이 값을 하드 코딩하는 대신 컨텍스트 프로세서를 사용하여이 값을 템플리트에 전달하는 것이 이상적이지만이 질문의 범위를 벗어납니다.

또한 URL / my_admin / jsi18n /을 django.views.i18n.javascript_catalog보기 (또는 I18N을 사용하지 않는 경우 null_javascript_catalog)에 수동으로 연결해야합니다. 관리자에게 로그인했는지 여부에 관계없이 액세스 할 수 있도록 관리자 응용 프로그램을 거치지 않고 직접해야합니다 ( 제레미 가 이것을 지적 해 주셔서 감사 합니다). URLconf의 샘플 코드 :

(r'^my_admin/jsi18n', 'django.views.i18n.javascript_catalog'),

마지막으로 Django 1.2 이상을 사용하는 경우 위젯이 미디어를 찾는 데 도움이되도록 템플릿에 추가 코드가 필요합니다.

{% load adminmedia %} /* At the top of the template. */

/* In the head section of the template. */
<script type="text/javascript">
window.__admin_media_prefix__ = "{% filter escapejs %}{% admin_media_prefix %}{% endfilter %}";
</script>

이 추가에 대해 lupefiasco 에게 감사드립니다 .


답변

솔루션이 hackish이기 때문에 JavaScript와 함께 날짜 / 시간 위젯을 사용하는 것이 더 적합하다고 생각합니다.


답변

네, 결국 / admin / jsi18n / url을 재정의했습니다.

urls.py에 추가 한 내용은 다음과 같습니다. / admin / url 위에 있는지 확인하십시오

    (r'^admin/jsi18n', i18n_javascript),

그리고 여기 내가 만든 i18n_javascript 함수가 있습니다.

from django.contrib import admin
def i18n_javascript(request):
  return admin.site.i18n_javascript(request)


답변

나는이 게시물을 많이 참조하고 문서에서 기본 위젯을 무시 하는 약간 덜 해킹 된 방법을 정의 한다는 것을 알았습니다 .

( ModelForm의 __init__ 메소드를 재정의 할 필요가 없습니다. )

그러나 Carl이 언급 한대로 JS와 CSS를 적절하게 연결해야합니다.

forms.py

from django import forms
from my_app.models import Product
from django.contrib.admin import widgets


class ProductForm(forms.ModelForm):
    mydate = forms.DateField(widget=widgets.AdminDateWidget)
    mytime = forms.TimeField(widget=widgets.AdminTimeWidget)
    mydatetime = forms.SplitDateTimeField(widget=widgets.AdminSplitDateTime)

    class Meta:
        model = Product

기본 양식 필드를 찾기위한 참조 필드 유형 .


답변

1.4 버전의 헤드 코드 (일부 새롭고 일부 제거됨)

{% block extrahead %}

<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}admin/css/forms.css"/>
<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}admin/css/base.css"/>
<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}admin/css/global.css"/>
<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}admin/css/widgets.css"/>

<script type="text/javascript" src="/admin/jsi18n/"></script>
<script type="text/javascript" src="{{ STATIC_URL }}admin/js/core.js"></script>
<script type="text/javascript" src="{{ STATIC_URL }}admin/js/admin/RelatedObjectLookups.js"></script>
<script type="text/javascript" src="{{ STATIC_URL }}admin/js/jquery.js"></script>
<script type="text/javascript" src="{{ STATIC_URL }}admin/js/jquery.init.js"></script>
<script type="text/javascript" src="{{ STATIC_URL }}admin/js/actions.js"></script>
<script type="text/javascript" src="{{ STATIC_URL }}admin/js/calendar.js"></script>
<script type="text/javascript" src="{{ STATIC_URL }}admin/js/admin/DateTimeShortcuts.js"></script>

{% endblock %}


답변

Django 1.2 RC1부터 Django 관리자 날짜 선택기 widge 트릭을 사용하는 경우 다음을 템플릿에 추가해야합니다. 그렇지 않으면 “/ missing-admin-media-prefix를 통해 달력 아이콘 URL이 참조됩니다. / “.

{% load adminmedia %} /* At the top of the template. */

/* In the head section of the template. */
<script type="text/javascript">
window.__admin_media_prefix__ = "{% filter escapejs %}{% admin_media_prefix %}{% endfilter %}";
</script>


답변

Carl Meyer의 답변을 보완하여 템플릿 내의 유효한 블록 (헤더 내부)에 해당 헤더를 넣어야한다고 언급하고 싶습니다.

{% block extra_head %}

<link rel="stylesheet" type="text/css" href="/media/admin/css/forms.css"/>
<link rel="stylesheet" type="text/css" href="/media/admin/css/base.css"/>
<link rel="stylesheet" type="text/css" href="/media/admin/css/global.css"/>
<link rel="stylesheet" type="text/css" href="/media/admin/css/widgets.css"/>

<script type="text/javascript" src="/admin/jsi18n/"></script>
<script type="text/javascript" src="/media/admin/js/core.js"></script>
<script type="text/javascript" src="/media/admin/js/admin/RelatedObjectLookups.js"></script>

{{ form.media }}

{% endblock %}