문제
기본 관리자가 내 사용자 정의 보기에 사용하는 멋진 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 달력 위젯을 찾아서 사용하는 것보다 구현하기가 쉽지 않습니다.
즉, 이 작업을 수행하기로 결정한 경우 수행해야 할 작업은 다음과 같습니다.
모델에 대한 자체 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()
'form_class'를 전달하도록 URLconf를 변경하십시오.'모델' 대신 ProductForm:Product를 일반 create_object 뷰로 전환합니다(물론 "from my_app.models import Product" 대신 "from my_app.forms import ProductForm"을 의미함).
템플릿 헤드에 {{ form.media }}를 포함하여 Javascript 파일에 대한 링크를 출력합니다.
그리고 해킹된 부분은 다음과 같습니다.관리 날짜/시간 위젯은 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'),
나는 이것을 사용하는데 훌륭하지만 템플릿에 두 가지 문제가 있습니다.
- 캘린더 아이콘이 표시됩니다. 두 배 템플릿에 제출된 모든 항목에 대해.
그리고 TimeField의 경우 '유효한 날짜를 입력하세요.'
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 %}