2010-03-04 4 views
2

У меня есть 3 модели с различными полями в каждом. Для 2 моделей, я отлично использую общую форму (через Django's create_object) для запроса данных. Я написал функцию, которая принимает название модели и отправляет пользователя в общей формеDjango: отображение общей модели модели или предопределенной формы

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

Для 3-й модели, я класс ModelForm определяется так, что я могу пропустить одно из полей в этой модели, когда пользователь видит форму.

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

Есть ли способ для Django, чтобы отобразить определенный ModelForm, если она существует, но в остальном полностью отобразить общий вид, если определенная форма не была сделана? Я ожидаю создания еще многих моделей и не буду создавать URL-адрес для каждой отдельной модели, которая должна быть разделена так, как это делается.

Итак, по-другому, я хочу изменить функцию generic_add, чтобы он использовал ActorForm (если он существует), но в противном случае общий ModelForm. Я знаю, как проверить существование класса ActorForm, но что, если я хочу, чтобы это было динамичным? Что-то вроде проверки, если: modelname + 'Form' существует. Я не уверен, как динамически отправлять пользователя в предопределенную форму, если таковая существует.

Любые предложения? Есть ли лучший способ взглянуть на эту проблему?

+0

У меня тяжелое время, следуя тому, что вы пытаетесь выполнить в целом из своего описания. Удобно ли вы вставлять соответствующие биты в мусорный контейнер где-то, чтобы мы могли видеть, что у вас есть до сих пор? –

+0

Извинения, см. Пересмотренный вопрос –

ответ

0

Было бы очень полезно увидеть эту функцию, о которой вы говорите.
Обычный способ использования create_object - это действительно указать модель или форму, которую вы хотите использовать, что приведет к появлению трех URL-адресов в вашем случае.

От documentation:

Необходимые аргументы:

  • Либо form_class или model требуется.
    Если вы предоставите form_class, это должен быть подкласс django.forms.ModelForm. Используйте этот аргумент, если вам нужно настроить форму модели. Дополнительную информацию см. В документах ModelForm.
    В противном случае model должен быть классом модели Django, а используемая форма будет стандартом ModelForm для модели.

Вы видите, что можете указать используемую форму. Может быть, это уже помогает вам, но без дополнительной информации мы не можем сделать больше.

+0

Я пересмотрел свой вопрос выше. Но в основном, я хочу иметь возможность использовать form_class, если он существует, но в остальном стандартный ModelForm –

1

Вот как я бы, наверное, подходить, что вы пытаетесь сделать:

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

Я не проверял это, но он должен работать нормально, дайте мне знать, если это Безразлично» так как я могу использовать что-то подобное в моих собственных проектах по дороге.

Кроме того, вы также можете сделать этот шаг дальше и создать еще один слой в файле model_presets dict, чтобы аналогичная вспомогательная функция создавала конфигурации для любых других общих представлений, которые вы можете использовать.

BTW, нет необходимости вставлять True в кавычки, просто запомните заглавные буквы T, а не rue, и оно будет разрешено для 1-битовой булевой константы. Использование «True» использует (приблизительный) минимум 32 бита в качестве строки. Оба будут проверять истинность в выражении if, и, таким образом, это не так уж важно для сделки. С другой стороны использование «False» не будет работать так, как ожидалось, так как еще раз это строка не логическая и, следовательно, также будет проверяться как истина.

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