2010-03-04 20 views
2

J'ai 3 modèles avec différents champs dans chacun. Pour deux des modèles, j'utilise un formulaire générique (via create_object de Django) pour demander des données. J'ai écrit une fonction qui accepte le nom du modèle et envoie à l'utilisateur de la forme génériqueDjango: Afficher un modèle générique ou un formulaire prédéfini

url(r'^add_(?P<modelname>\w+)/$', generic_add), 

def generic_add(request, modelname): 
    mdlnm_model = models.get_model('catalog',modelname) 
    return create_object(request, 
     model = mdlnm_model, 
     template_name = 'create.html', 
     post_save_redirect = '/library/', 
     extra_context = {'func': 'Create ' + modelname}, 
     login_required = 'True' 
    ) 

Pour le 3ème modèle, j'ai une classe ModelForm définie afin que je puisse omettre un des champs dans ce modèle lorsque l'utilisateur voit la forme.

url(r'^create_actor/$', create_object, Actor_Input, name='db_actor_create'), 

Actor_Input = { 
    'form_class': ActorForm, 
    'template_name': 'create.html', 
    'post_save_redirect': '/library/', 
    'extra_context': {'func': 'Create Actor'}, 
    'login_required': 'True' 
} 

class ActorForm(forms.ModelForm): 
    class Meta: 
      model = Actor 
      fields = ('name','age','height','short_description', 
        'long_description') 

est-il un moyen de Django pour afficher le ModelForm défini si elle existe, mais sinon afficher la forme complètement générique si une forme définie n'a pas été fait? Je prévois de créer beaucoup plus de modèles, et je préfère ne pas créer une URL pour chaque modèle qui doit être séparé de la façon dont Actor est.

Donc, de manière différente, je veux modifier la fonction generic_add afin qu'elle utilise ActorForm (si elle existe) mais sinon le ModelForm générique. Je sais comment vérifier l'existence de la classe ActorForm, mais si je veux que ça soit aussi dynamique? Quelque chose comme vérifier if: modelname + 'Form' existe. Je ne sais pas comment envoyer dynamiquement l'utilisateur à un formulaire prédéfini s'il en existe un.

Des suggestions? Y a-t-il une meilleure façon de voir ce problème?

+0

J'ai du mal à suivre ce que vous essayez d'accomplir dans l'ensemble de votre description. Êtes-vous à l'aise de coller les morceaux pertinents dans une poubelle quelque part afin que nous puissions voir ce que vous avez jusqu'ici? –

+0

Excuses, s'il vous plaît voir la question révisée –

Répondre

0

Il serait très utile de voir cette fonction dont vous parlez.
La façon normale d'utiliser create_object est en effet de spécifier le modèle ou le formulaire que vous voulez utiliser, ce qui donnerait trois URL dans votre cas.

De l'documentation:

arguments requis:

  • Soit form_class ou model est nécessaire.
    Si vous fournissez form_class, il devrait s'agir d'une sous-classe django.forms.ModelForm. Utilisez cet argument lorsque vous devez personnaliser le formulaire du modèle. Voir les documents ModelForm pour plus d'informations.
    Sinon, model doit être une classe de modèle Django et le formulaire utilisé sera un ModelForm standard pour le modèle.

Vous voyez, vous pouvez spécifier le formulaire à utiliser. Peut-être que cela vous aide déjà, mais sans plus d'informations, nous ne pouvons pas faire plus.

+0

J'ai révisé ma question ci-dessus. Mais fondamentalement, je veux être en mesure d'utiliser un form_class s'il en existe un, mais sinon le ModelForm standard –

1

Voici comment je l'approche probablement ce que vous essayez de faire:

url(r'^add_(?P<model_name>\w+)/$', generic_add), 

model_presets = { 
    'Actor': { 
     'extra_context': {'func': 'Create Actor'}, 
     'form_class': ActorForm, 
     'login_required': True, 
     'post_save_redirect': '/library/', 
     'template_name': 'create.html' 
    }, 
    'default': { 
     'extra_context': {'func': 'Oops, something went wrong if you are seeing \ 
            this, it should have been overwritten!'}, 
     'form_class': None, 
     'login_required': True, 
     'model': None, 
     'post_save_redirect': '/library/', 
     'template_name': 'create.html' 
    } 
} 

def _create_object_conf_helper(request, model_name): 
    if model_name in model_presets: 
     conf = model_presets[model_name] 
    else: 
     try: 
      named_model = models.get_model('catalog', model_name) 
     except: 
      # do something here to protect your app! 
     conf = model_presets['default'] 
     conf['model'] = named_model 
     conf['extra_context']['func'] = 'Create %s' % model_name 
    conf['request'] = request 
    return conf 

def generic_add(request, model_name): 
    return create_object(**_create_object_conf_helper(request, model_name)) 

Je n'ai pas testé, mais il devrait fonctionner bien, laissez-moi savoir si elle n » Je vais peut-être utiliser quelque chose de similaire dans mes propres projets sur la route. En outre, vous pouvez également aller plus loin et créer un autre calque dans la dict model_presets pour permettre à une fonction d'assistance similaire de créer des configs pour toutes les vues génériques que vous utilisez.

BTW, il est nécessaire de joindre vrai entre guillemets, rappelez-vous juste pour tirer le T et non la rue et il résoudra le 1 bit constante booléenne. L'utilisation de 'True' utilise un minimum (approximatif) de 32 bits en tant que chaîne. Les deux vont tester vrai dans une déclaration if et donc ce n'est pas un gros problème. D'un autre côté, l'utilisation de 'False' ne fonctionnera pas comme prévu, car une fois de plus, il s'agit d'une chaîne qui n'est pas un booléen et qui sera donc aussi testée comme vraie.

Voir http://docs.python.org/library/stdtypes.html#truth-value-testing.