programing

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

bestprogram 2023. 6. 11. 11:05

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

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

Django 양식 문서를 살펴보았는데 django.contrib.admin에 대해 간단히 언급하고 있습니다.위젯을 사용하는 방법을 모르겠습니다.

여기 제가 적용하고 싶은 템플릿이 있습니다.

<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의 모든 것에 대해 잘 알지 못합니다. 그러니 진정하세요...

시간이 지남에 따라 이 답변의 복잡성이 증가하고 필요한 많은 해킹이 발생하기 때문에 이를 수행하지 않도록 주의를 기울여야 합니다.문서화되지 않은 관리자의 내부 구현 세부 사항에 의존하고 있으며, 향후 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. 를 "URLconf"를 합니다.'form_class': ProductForm'model': Productcreate_object뷰그의다니합미은것그)뷰(▁view▁(다▁mean니)를 의미합니다.from my_app.forms import ProductFormfrom my_app.models import Product물론).

  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"/>

미디어가 의미합니다.ADMIN_MEDIA_PREFIX는 /media있습니다. 할 수 는 /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>

이 추가에 대해 루페페아스코에게 감사드립니다.

솔루션이 해킹적이기 때문에 자바스크립트와 함께 당신만의 날짜/시간 위젯을 사용하는 것이 더 실현 가능하다고 생각합니다.

저는 이 게시물을 자주 참조하고 문서가 기본 위젯을 재정의하는 약간 덜 세련된 방법을 정의한다는 것을 알게 되었습니다.

(모델 양식의 __init__ 메서드를 재정의할 필요가 없습니다.)

하지만 칼이 언급한 것처럼 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 %}

네, 저는 결국 /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)

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

장고 >= 2.0의 경우

참고: 날짜-시간 필드에 관리 위젯을 사용하는 것은 좋지 않습니다. 부트스트랩이나 다른 CSS 프레임워크를 사용하는 경우 관리 스타일시트가 사이트 스타일시트와 충돌할 수 있기 때문입니다.만약 당신이 부트스트랩에 당신의 사이트를 구축하고 있다면, 나의 부트스트랩 날짜 선택기 위젯 django-bootstrap-date picker-plus를 사용하세요.

1단계: 추가javascript-catalog) 의 URL(앱이 URL아님로)urls.pyjava.

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

위의 내용이 실패할 경우 아래의 내용도 최후의 수단으로 작동합니다.

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

을 당신의.py 에 . forms.py 에 에.from django.forms.extras.widgets import SelectDateWidget

2021년 장고 3(3.2)에 대한 또 다른 간단한 솔루션은 Andw의 솔루션이 Firefox에서 작동하지 않기 때문입니다.

{% load static %}

{% block extrahead %}
{{ block.super }}
<script type="text/javascript" src="{% static 'admin/js/cancel.js' %}"></script>
<link rel="stylesheet" type="text/css" href="{% static 'admin/css/forms.css' %}">
<script src="{% url 'admin:jsi18n' %}"></script>
<script src="{% static 'admin/js/jquery.init.js' %}"></script>
<script src="{% static 'admin/js/core.js' %}"></script>
{{ form.media }}
{% endblock %}

<form action="" method="post">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Сохранить">
</form>

양식을 사용할 수 있습니다.예:

from django.contrib.admin import widgets
date_time = forms.SplitDateTimeField(widget=widgets.AdminSplitDateTime)

여기 @Sandeep의 아이디어에서 영감을 얻은 또 다른 2020 솔루션이 있습니다.아래와 같은 양식에서 이 요지에 있는 MinimalSplitDateTimeMultiWidget을 사용하여 최신 브라우저 날짜 및 시간 선택기를 사용할 수 있습니다(예: 'type': 'date').JS는 필요 없습니다.

class EditAssessmentBaseForm(forms.ModelForm):
    class Meta:
        model = Assessment
        fields = '__all__'

    begin = DateTimeField(widget=MinimalSplitDateTimeMultiWidget())

여기에 이미지 설명 입력

위젯에 클래스를 할당한 다음 해당 클래스를 JQuery 날짜 선택기에 바인딩하는 것은 어떻습니까?

장고가 형성됩니다.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();

required=False를 사용하여 SplitDateTime에 대한 솔루션 및 해결 방법 업데이트:

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,)

서식.

<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의 경우 '유효한 날짜 입력'이 있습니다.

    다음은 양식의 스크린샷입니다.

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 : url 패턴의 시작 부분에서

  from django.views.i18n import JavaScriptCatalog

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

my 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>

My Django 설정 : 1.11 부트스트랩 : 3.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 %}

2020년 6월 3일 (모든 답변이 작동하지 않았습니다. 제가 사용한 이 솔루션을 사용해 보십시오.시간 필드에만 해당)

단순 사용Charfield양식의 시간 필드( 예에서는 시작 및 )에 대해 입력합니다.

forms.py

우리는 사용할 수 있습니다.Form또는ModelForm여기서.

class TimeSlotForm(forms.ModelForm):
    start = forms.CharField(widget=forms.TextInput(attrs={'placeholder': 'HH:MM'}))
    end = forms.CharField(widget=forms.TextInput(attrs={'placeholder': 'HH:MM'}))

    class Meta:
        model = TimeSlots
        fields = ('start', 'end', 'provider')

뷰에서 문자열 입력을 시간 객체로 변환합니다.

import datetime
def slots():
    if request.method == 'POST':
        form = create_form(request.POST)
        if form.is_valid():                
            slot = form.save(commit=False)
            start = form.cleaned_data['start']
            end = form.cleaned_data['end']
            start = datetime.datetime.strptime(start, '%H:%M').time()
            end = datetime.datetime.strptime(end, '%H:%M').time()
            slot.start = start
            slot.end = end
            slot.save()

언급URL : https://stackoverflow.com/questions/38601/using-django-time-date-widgets-in-custom-form