2014-02-10 2 views
1

Рассмотрим модель:Каков правильный способ создания Django ModelForm в представлении создания/редактирования?

class MyModel(models.Model): 
    token = models.CharField(unique=True, db_index=True, max_length...) 
    name = models.CharField(...) 
    ... 

(За исключением: цель маркера является, чтобы быть альтернативой отображения и с использованием идентификатора в URL-адресов, это не является первичным ключом.)

и его форма :

class MyForm(forms.ModelForm): 
    ...  
    class Meta: 
     model = models.MyModel 
     fields = '__all__' # Django 1.6 

И его шаблон:

... 
<form action={% url 'create_or_edit_mymodel' %} ...>{% csrf_token %} 

    {{ form.token.as_hidden }} 

    <label for="id_name">Name:</label> 
    {{ form.name }} 
    ... 

И, окончательное ly, вид сверху:

def create_or_edit_mymodel(request, token=None): 

    # [A] Entering via a hyperlink with the token, editing existing model 
    if token: 
     m = models.MyModel.objects.filter(token=token).first() 
     form = forms.MyForm(instance=m) 

    # [B] Postback from form 
    elif request.POST: 
     form = forms.MyForm(request.POST) 

    # [C] Entering via a hyperlink without the token, creating new model 
    else: 
     m = create_new_mymodel(...) # somewhere else 
     form = forms.MyForm(instance=m) 

    if request.method == 'POST' and form.is_valid(): 
     saved = form.save() 
     # Determine if 'Save' or 'Save & Close' was clicked... assume 'Save'... 
     form = forms.MyForm(instance=saved) 

    return shortcuts.render(request, '...', { 'form': form }, context_instance=RequestContext(request)) 

Это не работает. Проблема заключается в том, что идентификатор модели не представляется доступным для Django, поэтому ввод в представлении в [A] заполняет форму всем, как ожидалось, но нажатие «Сохранить» и вход в представление в [B] пытается сохранить модель без идентификатора, а уникальное ограничение на поле «токен» срабатывает.

Я попытался добавить поле идентификатора в виде:

{{ form.id.as_hidden }} # or... 
{{ form.pk.as_hidden }} 

Но ничего не визуализируется.

Этот вид выглядит довольно неудобным для меня, поэтому я надеюсь, что я сделаю это сложнее, чем это должно быть.

ответ

2

Здесь вы должны пройти как request.POSTи экземпляр сформировать INIT:

# [B] Postback from form 
elif request.POST: 
    form = forms.MyForm(request.POST, instance=instance) 
+0

Где экземпляр приходит? Я просматриваю его снова, используя скрытое поле токена, как я это делаю в [A]? – Seth

+0

@Seth из аргумента представления (токен). Ваша форма 'action' должна указывать на то же местоположение с тем же самым токеном – ndpu

+0

Это больше не доступно в postback, но я могу вытащить его из request.POST. Я собираюсь отредактировать ваш ответ; надеюсь, вы не против. – Seth

Смежные вопросы