2009-03-20 6 views
4

Ceci est une suite à How do you change the default widget for all Django date fields in a ModelForm?. Supposons que vous ayez un très grand nombre de modèles (p. Ex. A-ZZZ) qui grandissent avec l'aide d'autres développeurs indépendants de votre volonté et que vous souhaitiez modifier la façon dont tous les champs de date sont entrés (p. Ex. jQueryUI). Quelle est la meilleure façon de s'assurer que tous les champs de date sont remplis en utilisant ce nouveau widget?Comment modifier le widget par défaut pour tous les champs de formulaire d'un certain type dans Django?

Une suggestion de la question citée était:

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

Cependant, est-ce possible de le faire où vous n'avez pas de explicites de ModelForm, mais les modèles url venir des modèles directement? à savoir la configuration de votre URL est likeso:

url(r'^A/?$', 'list_detail.object_list', SomeModelA) 

où SomeModelA est un modèle (pas une forme) qui est transformé en un ModelForm par Django en arrière-plan.

Actuellement, dans mon système, il n'y a pas de formulaires pour chaque modèle. Le seul but de créer des formulaires explicitement serait d'ajouter le formfield_callback suggéré dans la solution précédente, mais cela va à l'encontre des principes DRY, et serait sujet aux erreurs et nécessiterait beaucoup de travail.

J'ai considéré (comme suggéré dans le dernier fil) la création de mon propre champ qui a un widget spécial et l'utilise à la place de l'intégré. Ce n'est pas si laborieux, mais il pourrait être sujet à des erreurs (rien de bon qu'un grep n'a pas pu réparer, cependant).

Suggestions et pensées sont appréciées.

Répondre

7

Il semble que vous vouliez faire ce projet à l'échelle (c.-à-d. Que vous n'essayez pas de le faire dans certains cas, mais dans TOUS les cas dans votre application en cours d'exécution).

Une possibilité consiste à remplacer l'attribut widget de la classe DateField elle-même. Vous aurez besoin de le faire dans un endroit central ... quelque chose qui est garanti pour être chargé par chaque instance en cours d'exécution de l'application django. Middleware peut aider avec cela. Sinon, mettez-le simplement dans le fichier __init__ de votre application. Ce que vous voulez faire est de réattribuer la propriété du widget pour la classe forms.DateField elle-même. Lorsqu'un nouveau champ DateField est créé, Django vérifie si le code spécifie un widget particulier dans la définition de propriété de champ. Sinon, il utilise la valeur par défaut pour DateField. Je suppose que si un utilisateur dans votre scénario définissait vraiment un widget particulier, vous voudriez honorer cela malgré le changement de votre API globale.

Essayez cela comme un exemple de forcer la valeur par défaut à un autre widget de ... dans ce cas un HiddenInput:

from django import forms 
forms.DateField.widget = forms.HiddenInput 

class Foo(forms.Form): 
    a = forms.DateField() 

f = Foo() 
print f.fields['a'].widget 
# results in <django.forms.widgets.HiddenInput object at 0x16bd910> 
+0

C'est le billet. Je vous remercie. –

+0

Génial! Merci beaucoup! – dfrankow

Questions connexes