Representar un formulario web atractivo y fácil de usar requiere más que solo HTML; también requiere hojas de estilo CSS, y si desea utilizar widgets sofisticados “Web2.0”, es posible que también necesite incluir algo de JavaScript en cada página. La combinación exacta de CSS y JavaScript que se requiere para una página determinada dependerá de los widgets que se utilicen en esa página.
Aquí es donde entran las definiciones de activos. Django le permite asociar diferentes archivos, como hojas de estilo y scripts, con los formularios y widgets que requieren esos activos. Por ejemplo, si desea utilizar un calendario para representar DateFields, puede definir un widget de calendario personalizado. Este widget se puede asociar con CSS y JavaScript necesarios para representar el calendario. Cuando se utiliza el widget Calendario en un formulario, Django puede identificar los archivos CSS y JavaScript necesarios y proporcionar la lista de nombres de archivos en un formulario adecuado para su inclusión en su página web.
Administrador de activos y Django
La aplicación Django Admin define una serie de widgets personalizados para calendarios, selecciones filtradas, etc. Estos widgets definen los requisitos de los activos, y el administrador de Django usa los widgets personalizados en lugar de los valores predeterminados de Django. Las plantillas de administrador solo incluirán los archivos necesarios para representar los widgets en una página determinada.
Si le gustan los widgets que usa la aplicación Django Admin, ¡no dude en usarlos en su propia aplicación! Están todos almacenados en django.contrib.admin.widgets
.
¿Qué kit de herramientas de JavaScript?
Existen muchos kits de herramientas de JavaScript, y muchos de ellos incluyen widgets (como widgets de calendario) que se pueden utilizar para mejorar su aplicación. Django ha evitado deliberadamente bendecir cualquier kit de herramientas de JavaScript. Cada conjunto de herramientas tiene sus propias fortalezas y debilidades relativas; utilice el conjunto de herramientas que se adapte a sus necesidades. Django puede integrarse con cualquier kit de herramientas de JavaScript.
Activos como definición estática
La forma más sencilla de definir activos es mediante una definición estática. Usando este método, la declaración es un interno Media
clase. Las propiedades de la clase interna definen los requisitos.
He aquí un ejemplo:
from django import forms classCalendarWidget(forms.TextInput):classMedia: css ='all':('pretty.css',) js =('animations.js','actions.js')
Este código define un CalendarWidget
, que se basará en TextInput
. Cada vez que se utiliza CalendarWidget en un formulario, ese formulario se dirigirá para incluir el archivo CSS pretty.css
y los archivos JavaScript animations.js
y actions.js
.
Esta definición estática se convierte en tiempo de ejecución en una propiedad de widget denominada media
. La lista de activos de un CalendarWidget
instancia se puede recuperar a través de esta propiedad:
>>> w = CalendarWidget()>>>print(w.media)<link href="http://static.example.com/pretty.css"type="text/css" media="all" rel="stylesheet"><script src="http://static.example.com/animations.js"></script><script src="http://static.example.com/actions.js"></script>
Aquí hay una lista de todos los posibles Media
opciones. No hay opciones obligatorias.
css
Un diccionario que describe los archivos CSS necesarios para varias formas de medios de salida.
Los valores del diccionario deben ser una tupla / lista de nombres de archivos. Ver la sección de caminos para obtener detalles sobre cómo especificar rutas a estos archivos.
Las claves del diccionario son los tipos de medios de salida. Estos son los mismos tipos aceptados por los archivos CSS en las declaraciones de medios: ‘todos’, ‘aural’, ‘braille’, ‘en relieve’, ‘handheld’, ‘print’, ‘projection’, ‘screen’, ‘tty’ y ‘ televisor’. Si necesita tener diferentes hojas de estilo para diferentes tipos de medios, proporcione una lista de archivos CSS para cada medio de salida. El siguiente ejemplo proporcionaría dos opciones de CSS: una para la pantalla y otra para imprimir:
classMedia: css ='screen':('pretty.css',),'print':('newspaper.css',)
Si un grupo de archivos CSS es apropiado para varios tipos de medios de salida, la clave del diccionario puede ser una lista separada por comas de los tipos de medios de salida. En el siguiente ejemplo, los televisores y proyectores tendrán los mismos requisitos de medios:
classMedia: css ='screen':('pretty.css',),'tv,projector':('lo_res.css',),'print':('newspaper.css',)
Si se renderizara esta última definición de CSS, se convertiría en el siguiente HTML:
<link href="http://static.example.com/pretty.css"type="text/css" media="screen" rel="stylesheet"><link href="http://static.example.com/lo_res.css"type="text/css" media="tv,projector" rel="stylesheet"><link href="http://static.example.com/newspaper.css"type="text/css" media="print" rel="stylesheet">
js
Una tupla que describe los archivos JavaScript necesarios. Ver la sección de caminos para obtener detalles sobre cómo especificar rutas a estos archivos.
extend
Un comportamiento de herencia de definición booleana para Media
declaraciones.
De forma predeterminada, cualquier objeto que utilice una Media
La definición heredará todos los activos asociados con el widget principal. Esto ocurre independientemente de cómo el padre defina sus propios requisitos. Por ejemplo, si tuviéramos que extender nuestro widget de Calendario básico del ejemplo anterior:
>>>classFancyCalendarWidget(CalendarWidget):...classMedia:... css =...'all':('fancy.css',)...... js =('whizbang.js',)>>> w = FancyCalendarWidget()>>>print(w.media)<link href="http://static.example.com/pretty.css"type="text/css" media="all" rel="stylesheet"><link href="http://static.example.com/fancy.css"type="text/css" media="all" rel="stylesheet"><script src="http://static.example.com/animations.js"></script><script src="http://static.example.com/actions.js"></script><script src="http://static.example.com/whizbang.js"></script>
El widget FancyCalendar hereda todos los activos de su widget principal. Si no quieres Media
para ser heredado de esta manera, agregue un extend=False
declaración al Media
declaración:
>>>classFancyCalendarWidget(CalendarWidget):...classMedia:... extend =False... css =...'all':('fancy.css',)...... js =('whizbang.js',)>>> w = FancyCalendarWidget()>>>print(w.media)<link href="http://static.example.com/fancy.css"type="text/css" media="all" rel="stylesheet"><script src="http://static.example.com/whizbang.js"></script>
Si necesita aún más control sobre la herencia, defina sus activos usando un propiedad dinámica. Las propiedades dinámicas le brindan un control completo sobre qué archivos se heredan y cuáles no.
Media
como una propiedad dinámica
Si necesita realizar una manipulación más sofisticada de los requisitos de activos, puede definir la media
propiedad directamente. Esto se hace definiendo una propiedad de widget que devuelve una instancia de forms.Media
. El constructor de forms.Media
acepta css
y js
argumentos de palabras clave en el mismo formato que el utilizado en una definición de medio estático.
Por ejemplo, la definición estática de nuestro widget de calendario también podría definirse de forma dinámica:
classCalendarWidget(forms.TextInput):@propertydefmedia(self):return forms.Media(css='all':('pretty.css',), js=('animations.js','actions.js'))
Consulte la sección sobre objetos de medios para obtener más detalles sobre cómo construir valores de retorno para dinámicas media
propiedades.
Rutas en las definiciones de activos
Las rutas utilizadas para especificar activos pueden ser relativas o absolutas. Si un camino comienza con /
, http://
o https://
, se interpretará como una ruta absoluta y se dejará como está. Todas las demás rutas se antepondrán con el valor del prefijo apropiado. Si el django.contrib.staticfiles
La aplicación está instalada, se utilizará para publicar activos.
Ya sea que use o no django.contrib.staticfiles
, los STATIC_URL
y STATIC_ROOT
Se requieren configuraciones para representar una página web completa.
Para encontrar el prefijo apropiado para usar, Django verificará si el STATIC_URL
el ajuste no es None
y volver a usar automáticamente MEDIA_URL
. Por ejemplo, si el MEDIA_URL
porque tu sitio era 'http://uploads.example.com/'
y STATIC_URL
era None
:
>>>from django import forms >>>classCalendarWidget(forms.TextInput):...classMedia:... css =...'all':('/css/pretty.css',),...... js =('animations.js','http://othersite.com/actions.js')>>> w = CalendarWidget()>>>print(w.media)<link href="/css/pretty.css"type="text/css" media="all" rel="stylesheet"><script src="http://uploads.example.com/animations.js"></script><script src="http://othersite.com/actions.js"></script>
Pero si STATIC_URL
es 'http://static.example.com/'
:
>>> w = CalendarWidget()>>>print(w.media)<link href="/css/pretty.css"type="text/css" media="all" rel="stylesheet"><script src="http://static.example.com/animations.js"></script><script src="http://othersite.com/actions.js"></script>
O si staticfiles
se configura usando el ManifestStaticFilesStorage
:
>>> w = CalendarWidget()>>>print(w.media)<link href="/css/pretty.css"type="text/css" media="all" rel="stylesheet"><script src="https://static.example.com/animations.27e20196a850.js"></script><script src="http://othersite.com/actions.js"></script>
Media
objetos
Cuando interrogas al media
atributo de un widget o formulario, el valor que se devuelve es un forms.Media
objeto. Como ya hemos visto, la representación en cadena de un Media
objeto es el HTML requerido para incluir los archivos relevantes en el bloque de su página HTML.
Sin embargo, Media
los objetos tienen otras propiedades interesantes.
Subconjuntos de activos
Si solo desea archivos de un tipo en particular, puede usar el operador de subíndice para filtrar un medio de interés. Por ejemplo:
>>> w = CalendarWidget()>>>print(w.media)<link href="http://static.example.com/pretty.css"type="text/css" media="all" rel="stylesheet"><script src="http://static.example.com/animations.js"></script><script src="http://static.example.com/actions.js"></script>>>>print(w.media['css'])<link href="http://static.example.com/pretty.css"type="text/css" media="all" rel="stylesheet">
Cuando usa el operador de subíndice, el valor que se devuelve es un nuevo Media
objeto, pero que solo contiene los medios de interés.
Combinatorio Media
objetos
Media
los objetos también se pueden sumar. Cuando dos Media
se añaden objetos, el resultado Media
El objeto contiene la unión de los activos especificados por ambos:
>>>from django import forms >>>classCalendarWidget(forms.TextInput):...classMedia:... css =...'all':('pretty.css',)...... js =('animations.js','actions.js')>>>classOtherWidget(forms.TextInput):...classMedia:... js =('whizbang.js',)>>> w1 = CalendarWidget()>>> w2 = OtherWidget()>>>print(w1.media + w2.media)<link href="http://static.example.com/pretty.css"type="text/css" media="all" rel="stylesheet"><script src="http://static.example.com/animations.js"></script><script src="http://static.example.com/actions.js"></script><script src="http://static.example.com/whizbang.js"></script>
Orden de activos
El orden en el que se insertan los activos en el DOM suele ser importante. Por ejemplo, puede tener un script que dependa de jQuery. Por lo tanto, combinando Media
objetos intenta preservar el orden relativo en el que se definen los activos en cada Media
clase.
Por ejemplo:
>>>from django import forms >>>classCalendarWidget(forms.TextInput):...classMedia:... js =('jQuery.js','calendar.js','noConflict.js')>>>classTimeWidget(forms.TextInput):...classMedia:... js =('jQuery.js','time.js','noConflict.js')>>> w1 = CalendarWidget()>>> w2 = TimeWidget()>>>print(w1.media + w2.media)<script src="http://static.example.com/jQuery.js"></script><script src="http://static.example.com/calendar.js"></script><script src="http://static.example.com/time.js"></script><script src="http://static.example.com/noConflict.js"></script>
Combinatorio Media
objetos con activos en un orden conflictivo da como resultado una MediaOrderConflictWarning
.
Media
en formularios
Los widgets no son los únicos objetos que pueden tener media
definiciones – las formas también pueden definir media
. Las reglas para media
las definiciones de los formularios son las mismas que las reglas de los widgets: las declaraciones pueden ser estáticas o dinámicas; Las reglas de ruta y herencia para esas declaraciones son exactamente las mismas.
Independientemente de si define un media
declaración, todos Los objetos de forma tienen un media
propiedad. El valor predeterminado para esta propiedad es el resultado de agregar el media
definiciones para todos los widgets que forman parte del formulario:
>>>from django import forms >>>classContactForm(forms.Form):... date = DateField(widget=CalendarWidget)... name = CharField(max_length=40, widget=OtherWidget)>>> f = ContactForm()>>> f.media <link href="http://static.example.com/pretty.css"type="text/css" media="all" rel="stylesheet"><script src="http://static.example.com/animations.js"></script><script src="http://static.example.com/actions.js"></script><script src="http://static.example.com/whizbang.js"></script>
Si desea asociar activos adicionales con un formulario, por ejemplo, CSS para el diseño del formulario, agregue un Media
declaración al formulario:
>>>classContactForm(forms.Form):... date = DateField(widget=CalendarWidget)... name = CharField(max_length=40, widget=OtherWidget)......classMedia:... css =...'all':('layout.css',)...>>> f = ContactForm()>>> f.media <link href="http://static.example.com/pretty.css"type="text/css" media="all" rel="stylesheet"><link href="http://static.example.com/layout.css"type="text/css" media="all" rel="stylesheet"><script src="http://static.example.com/animations.js"></script><script src="http://static.example.com/actions.js"></script><script src="http://static.example.com/whizbang.js"></script>
Acuérdate de que tienes autorización de agregar una reseña si tropezaste tu atascamiento .