jquery - titel - title tag wordpress




Wie ändern Sie das Standardwidget für alle Django-Datumsfelder in einem ModelForm? (4)

Angesichts einer Reihe von typischen Modellen:

# Application A
from django.db import models
class TypicalModelA(models.Model):
    the_date = models.DateField()

 # Application B
from django.db import models
class TypicalModelB(models.Model):
    another_date = models.DateField()

...

Wie kann man das Standard-Widget für alle DateFields in ein benutzerdefiniertes MyDateWidget ändern?

Ich frage, weil ich möchte, dass meine Anwendung einen jQueryUI Datepicker für das Eingeben von Daten hat.

Ich habe ein benutzerdefiniertes Feld in Erwägung gezogen, das django.db.models.DateField mit meinem benutzerdefinierten Widget erweitert. Ist dies der beste Weg, um diese Art von Änderung zu implementieren? Solch eine Änderung erfordert das spezifische Importieren eines speziellen MyDateField in jedes Modell, das arbeitsintensiv ist, anfällig für Entwicklerfehler (dh ein paar Modelle.DateFields wird durchkommen), und in meinen Augen scheint wie unnötige Doppelarbeit. Auf der anderen Seite mag ich es nicht zu modifizieren, was als die kanonische Version von models.DateField angesehen werden könnte.

Gedanken und Input werden geschätzt.


Einige mögen die Stirn runzeln, aber um die Datumsauswahl durch Ihr benutzerdefiniertes Widget zu ersetzen, würde ich eine Monkeypatch-App für Ihr Projekt erstellen und Django selbst zur Laufzeit patchen. Davon profitieren auch Apps von Drittanbietern, die dem Endanwender eine einheitliche Oberfläche bieten, ohne den Drittanbieter-Code ändern zu müssen:

from django.forms.widgets import DateInput , DateTimeInput, TimeInput
from FOO.widgets import MyjQueryWidget

# be nice and tell you are patching
logger.info("Patching 'DateInput.widget = MyjQueryWidget': Replaces django DateInput to use my new super  'MyjQueryWidget'")

# be nicer and confirm signature of code we are patching and warn if it has changed - uncomment below to get the current hash fingerprint
# raise Exception(hashlib.md5(inspect.getsource(DateInput.widget)).hexdigest()) # uncommet to find latest hash
if not '<enter hexdigest fingerprint here>' == \
        hashlib.md5(inspect.getsource(DateInput.widget)).hexdigest():
    logger.warn("md5 signature of 'DateInput.widget' does not match Django 1.5. There is a slight chance patch "
                    "might be broken so please compare and update this monkeypatch.")

# be nicest and also update __doc__
DateInput.__doc__ = "*Monkeypatched by <app name>*: Replaced django DateInput.widget with my new super  'MyjQueryWidget'" + DateInput.__doc__ 

DateInput.widget = MyjQueryWidget

Das obige ist inspiriert von meinem html5monkeypatch, das ich als Teil meiner Projekte verwende, schau patch_widgets.py und patch_fields.py .


Ich benutze JQuery. Sie müssen nur nach der 'ID' der Felder suchen, die Sie mit der Datumsauswahl verknüpfen möchten, und sie mit JQuery und dem richtigen Anzeigeformat verknüpfen:

models.py

class ObjectForm(ModelForm):
    class Meta:
        model = Object        
        fields = ['FieldName1','FieldName2']

oben auf der Seite rendern Sie mit Ihrer Ansicht:

<head>
    <link type="text/css" href="/media/css/ui-darkness/jquery-ui-1.8.2.custom.css" rel="Stylesheet" /> 
    <script type="text/javascript" src="/media/js/jquery-1.4.2.min.js"></script>
    <script type="text/javascript" src="/media/js/jquery-ui-1.8.2.custom.min.js"></script>
</head>
<script type="text/javascript">
 $(function() {
        $("#id_FieldName1").datepicker({ dateFormat: 'yy-mm-dd' });
        $("#id_FieldName2").datepicker({ dateFormat: 'yy-mm-dd' });
 });
</script>
...
{{form}}

Sie können ein Attribut für Ihre ModelForm Klasse namens formfield_callback . Dies sollte eine Funktion sein, die eine Django-Modellfeldinstanz als Argument akzeptiert und eine Formularfeldinstanz zurückgibt, um sie im Formular darzustellen.

Dann müssen Sie nur nachsehen, ob das übergebene DateField eine Instanz von DateField und falls ja, geben Sie Ihr benutzerdefiniertes Feld / Widget zurück. Ist dies nicht der formfield , verfügt das formfield über eine Methode namens formfield , die Sie aufrufen können, um das Standardformularfeld zurückzugeben.

Also, etwas wie:

def make_custom_datefield(f):
    if isinstance(f, models.DateField):
        # return form field with your custom widget here...
    else:
        return f.formfield()

class SomeForm(forms.ModelForm)
    formfield_callback = make_custom_datefield

    class Meta:
        # normal modelform stuff here...

Sie möchten ein benutzerdefiniertes Widget definieren und die innere Media-Klasse des Widgets verwenden, um die JS-Dateien (und CSS?) Zu definieren, die auf der Seite enthalten sein müssen, damit das Widget funktioniert. Wenn Sie dies richtig machen, können Sie Ihr Widget vollständig eigenständig und wiederverwendbar machen. Ein Beispiel dafür finden Sie unter django-markitup (es gibt ein wiederverwendbares Widget für den MarkUpUp! Universal-Markup-Editor ).

Dann benutze formfield_callback (siehe James Bennetts Antwort), um dieses Widget einfach auf alle DateFields in einem Formular anzuwenden.





django-widget