문제

기본 관리자가 내 사용자 정의 보기에 사용하는 멋진 JavaScript 날짜 및 시간 위젯을 어떻게 사용할 수 있나요?

나는 살펴보았다 Django 양식 문서, 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': ''}),

그리고 저는 Django/MVC/MTV 전체에 대해 처음 접하는 사람이므로 쉽게 넘어가시기 바랍니다...

도움이 되었습니까?

해결책

시간이 지남에 따라 이 답변의 복잡성이 증가하고 많은 해킹이 필요하므로 이 작업을 전혀 수행하지 않도록 주의해야 할 것입니다.이는 관리자의 문서화되지 않은 내부 구현 세부 사항에 의존하고 있으며 향후 버전의 Django에서 다시 중단될 가능성이 높으며 다른 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. 'form_class'를 전달하도록 URLconf를 변경하십시오.'모델' 대신 ProductForm:Product를 일반 create_object 뷰로 전환합니다(물론 "from my_app.models import Product" 대신 "from 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>
    

    다음 관리 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>

감사해요 루페피아스코 이 추가를 위해.

다른 팁

해결책이 해킹적이기 때문에 일부 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)

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 %}

나는 이 게시물을 많이 참조하고 있으며, 선적 서류 비치 정의하다 약간 기본 위젯을 재정의하는 덜 해킹적인 방법입니다.

(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

참조 필드 유형 기본 양식 필드를 찾으려면

Django 1.2 RC1부터 Django 관리 날짜 선택기 위젯 트릭을 사용하는 경우 템플릿에 다음을 추가해야 합니다. 그렇지 않으면 "/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 %}

위의 방법이 실패한 경우 아래 방법도 최후의 수단으로 사용할 수 있습니다.

class PaymentsForm(forms.ModelForm):
    class Meta:
        model = Payments

    def __init__(self, *args, **kwargs):
        super(PaymentsForm, self).__init__(*args, **kwargs)
        self.fields['date'].widget = SelectDateWidget()

와 동일

class PaymentsForm(forms.ModelForm):
    date = forms.DateField(widget=SelectDateWidget())

    class Meta:
        model = Payments

이것을 form.py에 넣으세요 from django.forms.extras.widgets import SelectDateWidget

위젯에 클래스를 할당한 다음 해당 클래스를 JQuery 날짜 선택기에 바인딩하면 어떨까요?

장고 form.py:

class MyForm(forms.ModelForm):

  class Meta:
    model = MyModel

  def __init__(self, *args, **kwargs):
    super(MyForm, self).__init__(*args, **kwargs)
    self.fields['my_date_field'].widget.attrs['class'] = 'datepicker'

그리고 템플릿에 대한 일부 JavaScript는 다음과 같습니다.

  $(".datepicker").datepicker();

장고 >= 2.0의 경우

메모:날짜-시간 필드에 관리 위젯을 사용하는 것은 좋은 생각이 아닙니다. 부트스트랩이나 다른 CSS 프레임워크를 사용하는 경우 관리 스타일 시트가 사이트 스타일 시트와 충돌할 수 있기 때문입니다.부트스트랩에서 사이트를 구축하는 경우 내 bootstrap-datepicker 위젯을 사용하세요. 장고-부트스트랩-날짜 선택기-플러스.

1 단계: 추가하다 javascript-catalog 프로젝트(앱 아님)의 URL urls.py 파일.

from django.views.i18n import JavaScriptCatalog

urlpatterns = [
    path('jsi18n', JavaScriptCatalog.as_view(), name='javascript-catalog'),
]

2 단계: 템플릿에 필수 JavaScript/CSS 리소스를 추가하세요.

<script type="text/javascript" src="{% url 'javascript-catalog' %}"></script>
<script type="text/javascript" src="{% static '/admin/js/core.js' %}"></script>
<link rel="stylesheet" type="text/css" href="{% static '/admin/css/widgets.css' %}">
<style>.calendar>table>caption{caption-side:unset}</style><!--caption fix for bootstrap4-->
{{ form.media }}        {# Form required JS and CSS #}

3단계: 날짜-시간 입력 필드에 관리 위젯을 사용하세요. forms.py.

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

class ProductCreateForm(forms.ModelForm):
    class Meta:
        model = Product
        fields = ['name', 'publish_date', 'publish_time', 'publish_datetime']
        widgets = {
            'publish_date': widgets.AdminDateWidget,
            'publish_time': widgets.AdminTimeWidget,
            'publish_datetime': widgets.AdminSplitDateTime,
        }

업데이트된 솔루션 및 해결 방법 분할 날짜시간 ~와 함께 필수=거짓:

Forms.py

from django import forms

class SplitDateTimeJSField(forms.SplitDateTimeField):
    def __init__(self, *args, **kwargs):
        super(SplitDateTimeJSField, self).__init__(*args, **kwargs)
        self.widget.widgets[0].attrs = {'class': 'vDateField'}
        self.widget.widgets[1].attrs = {'class': 'vTimeField'}  


class AnyFormOrModelForm(forms.Form):
    date = forms.DateField(widget=forms.TextInput(attrs={'class':'vDateField'}))
    time = forms.TimeField(widget=forms.TextInput(attrs={'class':'vTimeField'}))
    timestamp = SplitDateTimeJSField(required=False,)

form.html

<script type="text/javascript" src="/admin/jsi18n/"></script>
<script type="text/javascript" src="/admin_media/js/core.js"></script>
<script type="text/javascript" src="/admin_media/js/calendar.js"></script>
<script type="text/javascript" src="/admin_media/js/admin/DateTimeShortcuts.js"></script>

urls.py

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

나는 이것을 사용하는데 훌륭하지만 템플릿에 두 가지 문제가 있습니다.

  1. 캘린더 아이콘이 표시됩니다. 두 배 템플릿에 제출된 모든 항목에 대해.
  2. 그리고 TimeField의 경우 '유효한 날짜를 입력하세요.'

    Here is a screenshot of the Form

models.py

from django.db import models
    name=models.CharField(max_length=100)
    create_date=models.DateField(blank=True)
    start_time=models.TimeField(blank=False)
    end_time=models.TimeField(blank=False)

Forms.py

from django import forms
from .models import Guide
from django.contrib.admin import widgets

class GuideForm(forms.ModelForm):
    start_time = forms.DateField(widget=widgets.AdminTimeWidget)
    end_time = forms.DateField(widget=widgets.AdminTimeWidget)
    create_date = forms.DateField(widget=widgets.AdminDateWidget)
    class Meta:
        model=Guide
        fields=['name','categorie','thumb']

장고 10에서.myproject/urls.py:urlpatterns의 시작 부분에

  from django.views.i18n import JavaScriptCatalog

urlpatterns = [
    url(r'^jsi18n/$', JavaScriptCatalog.as_view(), name='javascript-catalog'),
.
.
.]

내 template.html에서:

{% load staticfiles %}

    <script src="{% static "js/jquery-2.2.3.min.js" %}"></script>
    <script src="{% static "js/bootstrap.min.js" %}"></script>
    {# Loading internazionalization for js #}
    {% load i18n admin_modify %}
    <script type="text/javascript" src="{% url 'javascript-catalog' %}"></script>
    <script type="text/javascript" src="{% static "/admin/js/jquery.init.js" %}"></script>

    <link rel="stylesheet" type="text/css" href="{% static "/admin/css/base.css" %}">
    <link rel="stylesheet" type="text/css" href="{% static "/admin/css/forms.css" %}">
    <link rel="stylesheet" type="text/css" href="{% static "/admin/css/login.css" %}">
    <link rel="stylesheet" type="text/css" href="{% static "/admin/css/widgets.css" %}">



    <script type="text/javascript" src="{% static "/admin/js/core.js" %}"></script>
    <script type="text/javascript" src="{% static "/admin/js/SelectFilter2.js" %}"></script>
    <script type="text/javascript" src="{% static "/admin/js/admin/RelatedObjectLookups.js" %}"></script>
    <script type="text/javascript" src="{% static "/admin/js/actions.js" %}"></script>
    <script type="text/javascript" src="{% static "/admin/js/calendar.js" %}"></script>
    <script type="text/javascript" src="{% static "/admin/js/admin/DateTimeShortcuts.js" %}"></script>

내 장고 설정:1.11 부트 스트랩 :3.3.7

완전히 명확한 답변은 없으므로 오류가 전혀 없는 템플릿 코드를 공유하고 있습니다.

템플릿의 위쪽 절반:

{% extends 'base.html' %}
{% load static %}
{% load i18n %}

{% block head %}
    <title>Add Interview</title>
{% endblock %}

{% block content %}

<script type="text/javascript" src="{% url 'javascript-catalog' %}"></script>
<script type="text/javascript" src="{% static 'admin/js/core.js' %}"></script>
<link rel="stylesheet" type="text/css" href="{% static 'admin/css/forms.css' %}"/>
<link rel="stylesheet" type="text/css" href="{% static 'admin/css/widgets.css' %}"/>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" >
<script type="text/javascript" src="{% static 'js/jquery.js' %}"></script>

하반부:

<script type="text/javascript" src="/admin/jsi18n/"></script>
<script type="text/javascript" src="{% static 'admin/js/vendor/jquery/jquery.min.js' %}"></script>
<script type="text/javascript" src="{% static 'admin/js/jquery.init.js' %}"></script>
<script type="text/javascript" src="{% static 'admin/js/actions.min.js' %}"></script>
{% endblock %}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top