Делаете Django ModelForm типовой модели? - PullRequest
1 голос
/ 15 августа 2011

Я столкнулся с интересной ситуацией с Django, и я надеялся, что кто-нибудь найдет решение этой проблемы, или, по крайней мере, мог бы дать мне подсказку.

Я пытаюсь сделать ModelForm универсальным для модели.Я не знаю, если это то, что должно быть сделано, но здесь это идет.

Это прекрасно работает:

кортеж, ссылающийся на модели

# settings.py
SPECIES = (
    ('TIG', 'Tiger'),
    ('SHR', 'Shark'),
)

URL-адрес для создания объекта Animal

# urls.py
from django.conf.urls.defaults import patterns, include, url
urlpatterns = patterns('species.views',
    url(r'^add/$', 'add_animal', name='add_animal'),
)

Модель Animal и два его потомка

# models.py
from django.db import models
from django.conf import settings

class Animal(models.Model):
    name = models.CharField(max_length=100)
    nickname = models.CharField(max_length=100)
    species = models.CharField(max_length=3, choices=settings.SPECIES)

class Tiger(Animal):
    fangs_size = models.IntegerField()

class Shark(Animal):
    color = models.CharField(max_length=20)

Вид, отображающий форму

Правильная модель выбирается с помощью параметра GET.

# views.py
def add_animal(request):
    if request.method == "GET":
        if request.GET['model_name']:
            model_name = request.GET['model_name']
    else:
        model_name = 'Animal'

    print "Model name is: %s" % model_name

    model = get_model("species", model_name)
    form = AnimalForm(model=model)

    return create_object(
        request,
        model=model,
        post_save_redirect=reverse('index'),
        template_name='species/my_form.html',
    )

Шаблон

# my_form.html
<!doctype html>
<html>
    <head>
        <title>Adding an animal</title>
    </head>
    <body>
        <h1>Add an animal to the farm</h1>
        <form>
            {% csrf_token %}
            {{ form.as_p }}
            <input type="submit" value="Submit" />
        </form>
    </body>
</html>

Когда я захожу / add? Model_name = tiger , я получаю правильную форму.

Теперь, допустим, я хочу скрыть поле псевдонима.Затем мне нужно будет использовать пользовательскую ModelForm.Как воплотить это в жизнь с правильной моделью?Это моя проблема.

Вот форма?

# forms.py
from species.models import Animal
from django import forms

class AnimalForm(forms.ModelForm):

    class Meta:
        model = Animal

    def __init__(self, *args, **kwargs):
        model = kwargs.pop('model')
        super(AnimalForm, self).__init__(*args, **kwargs)
        self.Meta.model = model

Вид становится:

# views.py
...
model = get_model("species", model_name)
form = AnimalForm(model=model)

return create_object(
    request,
    # model=model,            # Need for customization
    # form_class=AnimalForm,  # With the class name, how to pass the argument?
    form_class=form,          # Not sure this can be done, I get this error: 'AnimalForm' object is not callable
    post_save_redirect=reverse('index'),
    template_name='species/my_form.html',
)
...

МойЦель состоит в том, чтобы иметь возможность создавать новые модели, унаследованные от Animal, позже, добавить их в кортеж SPECIES и все готово.Можно ли это сделать?

Спасибо за помощь!

1 Ответ

5 голосов
/ 15 августа 2011

Возможно, вы захотите использовать django.forms.models.modelform_factory - он принимает класс модели и кортеж exclude среди своих параметров. Вы можете использовать его в представлении для динамического создания класса формы.

form_class = modelform_factory(model, exclude=('nickname',))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...