如何使用默认管理员在自定义视图中使用的漂亮的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>
Run Code Online (Sandbox Code Playgroud)
此外,我认为应该注意的是,我没有真正为自己的表单编写视图,我使用的是通用视图.这是来自url.py的条目:
(r'^admin/products/add/$', create_object, {'model': Product, 'post_save_redirect': ''}),
Run Code Online (Sandbox Code Playgroud)
而且我对整个Django/MVC/MTV事物都是新手,所以请轻松一点......
Car*_*yer 159
随着时间的推移,这个答案越来越复杂,以及所需的许多黑客,可能应该提醒你不要这样做.它依赖于管理员的未记录的内部实现细节,可能会在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()
Run Code Online (Sandbox Code Playgroud)更改您的URLconf以传递'form_class':ProductForm而不是'model':产品到通用create_object视图(这意味着"来自my_app.forms导入ProductForm"而不是"来自my_app.models导入产品",当然).
在模板的头部,包含{{form.media}}以输出指向Javascript文件的链接.
而hacky部分:管理日期/时间小部件假设已经加载了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>
Run Code Online (Sandbox Code Playgroud)
您可能还希望使用以下管理CSS(感谢Alex提及此内容):
<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"/>
Run Code Online (Sandbox Code Playgroud)这意味着Django的管理媒体(ADMIN_MEDIA_PREFIX)位于/ media/admin/ - 您可以为您的设置更改它.理想情况下,您使用上下文处理器将此值传递给模板而不是对其进行硬编码,但这超出了此问题的范围.
这还要求将URL/my_admin/jsi18n /手动连接到django.views.i18n.javascript_catalog视图(如果不使用I18N,则为null_javascript_catalog).你必须自己这样做,而不是通过管理应用程序,所以无论你是否登录管理员都可以访问它(感谢Jeremy指出这一点).您的URLconf的示例代码:
(r'^my_admin/jsi18n', 'django.views.i18n.javascript_catalog'),
Run Code Online (Sandbox Code Playgroud)
最后,如果您使用的是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>
Run Code Online (Sandbox Code Playgroud)
感谢lupefiasco的加入.
zgo*_*oda 63
由于解决方案是hackish,我认为使用自己的日期/时间小部件与一些JavaScript是更可行的.
小智 12
是的,我最终覆盖了/ admin/jsi18n/url.
这是我在urls.py中添加的内容.确保它在/ admin/url之上
(r'^admin/jsi18n', i18n_javascript),
Run Code Online (Sandbox Code Playgroud)
这是我创建的i18n_javascript函数.
from django.contrib import admin
def i18n_javascript(request):
return admin.site.i18n_javascript(request)
Run Code Online (Sandbox Code Playgroud)
mon*_*kut 11
我发现自己经常引用这篇文章,并发现文档定义了一种稍微不那么粗暴的方式来覆盖默认小部件.
(无需覆盖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
Run Code Online (Sandbox Code Playgroud)
参考字段类型以查找默认表单字段.
小智 11
我的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 %}
Run Code Online (Sandbox Code Playgroud)
msh*_*rir 10
从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>
Run Code Online (Sandbox Code Playgroud)
作为对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 %}
Run Code Online (Sandbox Code Playgroud)
注意:对日期时间字段使用管理小部件不是一个好主意,因为如果您使用引导程序或任何其他 CSS 框架,管理样式表可能会与您的站点样式表发生冲突。如果您在 bootstrap 上构建站点,请使用我的 bootstrap-datepicker 小部件django-bootstrap-datepicker-plus。
第 1 步:将javascript-catalog
URL添加到您的项目(不是应用程序)urls.py
文件中。
from django.views.i18n import JavaScriptCatalog
urlpatterns = [
path('jsi18n', JavaScriptCatalog.as_view(), name='javascript-catalog'),
]
Run Code Online (Sandbox Code Playgroud)
第 2 步:将所需的 JavaScript/CSS 资源添加到您的模板中。
from django.views.i18n import JavaScriptCatalog
urlpatterns = [
path('jsi18n', JavaScriptCatalog.as_view(), name='javascript-catalog'),
]
Run Code Online (Sandbox Code Playgroud)
第 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,
}
Run Code Online (Sandbox Code Playgroud)
如果上述失败,下面也将作为最后的手段
class PaymentsForm(forms.ModelForm):
class Meta:
model = Payments
def __init__(self, *args, **kwargs):
super(PaymentsForm, self).__init__(*args, **kwargs)
self.fields['date'].widget = SelectDateWidget()
Run Code Online (Sandbox Code Playgroud)
与...一样
class PaymentsForm(forms.ModelForm):
date = forms.DateField(widget=SelectDateWidget())
class Meta:
model = Payments
Run Code Online (Sandbox Code Playgroud)
把它放在你的forms.py中 from django.forms.extras.widgets import SelectDateWidget
2021 年 Django 3 (3.2)的另一个简单解决方案;) 因为 andyw 的解决方案在 Firefox 中不起作用......
\n{% load static %}\n\n{% block extrahead %}\n{{ block.super }}\n<script type="text/javascript" src="{% static 'admin/js/cancel.js' %}"></script>\n<link rel="stylesheet" type="text/css" href="{% static 'admin/css/forms.css' %}">\n<script src="{% url 'admin:jsi18n' %}"></script>\n<script src="{% static 'admin/js/jquery.init.js' %}"></script>\n<script src="{% static 'admin/js/core.js' %}"></script>\n{{ form.media }}\n{% endblock %}\n\n<form action="" method="post">\n{% csrf_token %}\n{{ form.as_p }}\n<input type="submit" value="\xd0\xa1\xd0\xbe\xd1\x85\xd1\x80\xd0\xb0\xd0\xbd\xd0\xb8\xd1\x82\xd1\x8c">\n</form>\n
Run Code Online (Sandbox Code Playgroud)\n您将能够使用您的表单。\n示例:
\nfrom django.contrib.admin import widgets\ndate_time = forms.SplitDateTimeField(widget=widgets.AdminSplitDateTime)\n
Run Code Online (Sandbox Code Playgroud)\n
归档时间: |
|
查看次数: |
111284 次 |
最近记录: |