2010-09-22 4 views
5

Я пытаюсь создать простой CRUD с ModelForm. Он отлично работает, за исключением того, что каждый раз, когда я редактирую, сохранение создает новый экземпляр данных. Поэтому я редактирую и получаю дополнительную строку в БД вместо обновленной. Я не понимаю, как это известно, чтобы сохранить существующую благотворительность, поскольку она не хранит PK (id) как скрытое поле в форме. Именно так я всегда делал это, прежде чем пытаться использовать «потрясающий» ModelForm!Django ModelForm

Это сводит меня с ума, я все прочитал, и насколько я могу судить, я все делаю правильно.

Вот мой код ..

Модель:

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

COUNTRY_CHOICES = settings.COUNTRIES 

class Charities(models.Model): 
    charity_name   = models.CharField(max_length=100) 
    country     = models.CharField(max_length=4, choices=COUNTRY_CHOICES) 
    registration_number  = models.CharField(max_length=100) 
    address1    = models.CharField(max_length=100) 
    address2    = models.CharField(max_length=100) 
    city     = models.CharField(max_length=30) 
    zip      = models.CharField(max_length=10) 
    phone     = models.CharField(max_length=20) 
    email     = models.EmailField() 
    charity_logo_image  = models.CharField(max_length=100) 
    charity_banner_image = models.CharField(max_length=100) 
    charity_accepted  = models.IntegerField() 

    def __str__(self): 
     return self.charity_name 

    def __unicode__(self): 
     self.charity_name 

Вид:

def list(request): 
    charities = Charities.objects.all() 
    return render_to_response('charities_charity_list.html', {'charities': charities}) 

def add(request): 
    return add_or_edit(request) 

def edit(request, charity_id): 
    return add_or_edit(request, charity_id) 

def add_or_edit(request, charity_id=None): 
    print "ID = " + str(charity_id) 
    form = CharityForm(request.POST or None, 
        instance=charity_id and Charities.objects.get(pk=charity_id)) 

    # Save new/edited student 
    if request.method == 'POST' and form.is_valid(): 
     print form 
     form.save() 
     return HttpResponseRedirect('/charities/list/') 

    return render_to_response('charities_charity_edit.html', {'form': form}) 

Форма:

class CharityForm(ModelForm): 
    class Meta: 
     model = Charities 

Шаблон:

{% extends "base.html" %} 

{% block title %}Charities Add{% endblock %} 
{% block content %} 

<form method="post" action="/charities/add/" id="save"><table cellpadding="0">{{ form.as_table}}</table><input type="submit" value="Save"></form> 
{% endblock %} 

ответ

5

Это не работает, потому что ваш шаблон всегда отправляется в представление, которое добавляет новую благотворительность. Когда вы вручную вводите URL-адрес, например/charities/edit/5, он создает ModelForm с правильными исходными данными, но затем POSTs/charities/add, создавая таким образом новый экземпляр. Например, вам нужно отправить POST на/благотворительные/правые/5. Взгляните на шаблон шаблона URL-адреса.

Предлагаю вам использовать 2 шаблона, один для добавления, другой для редактирования. Я знаю, что это может быть не очень СУХОЙ, но я считаю, что это яснее.

Добавить шаблон:

{% extends "base.html" %} 

{% block title %}Charities Add{% endblock %} 
{% block content %} 

<form method="post" action="{% url charities_app.views.add %}"><table cellpadding="0">{{ form.as_table}}</table><input type="submit" value="Save"></form> 
{% endblock %} 

Изменить шаблон:

{% extends "base.html" %} 

{% block title %}Edit Charity{% endblock %} 
{% block content %} 

<form method="post" action="{% url charities_app.views.edit charity.id %}"><table cellpadding="0">{{ form.as_table}}</table><input type="submit" value="Save"></form> 
{% endblock %} 

Вы также можете проверить create_object и update_object общие взгляды, они очень полезны в простых случаях, как ваш.

+0

Hi Tiago, спасибо, что ответили. Раньше я не слышал об общих параметрах. я буду читать их. Просто пытаюсь заставить существующий метод работать, я не могу извлечь идентификатор из charity.id, чтобы добавить его к URL-адресу редактирования. Я тоже попробовал form.id, но это просто не в контексте. Кроме того, что такое charities_app? это вы просто помещаете в заполнитель для замены? В моем членском представлении я попытался использовать {% url race.members.views.edit member.id%}, но получил ошибку ............... Caught ViewDoesNotExist при рендеринге: пробовал домой в модульной гонке .charities.views. – Rich

+0

Я тупо забыл, что могу передать член/благотворительность Id через контекст. Поэтому у меня теперь есть ID в URL-адресе редактирования, и он работает, конечно. Благодарю. Теперь я просто пытаюсь понять, как заменить URL-адрес действия похожим на ваш пример {% url charities_app.views.edit charity.id%}. Что такое charities_app. Должна ли это быть точкой зрения? мне нужно определить get_absolute_url? – Rich

+0

Привет, в этом случае charities_app будет именем приложения, которое содержит модель Charities. charities_app.view.edit - это просто имя представления, которое будет обрабатывать запрос. Этот URL-адрес полезен, потому что вам не нужно жестко привязывать URL-адреса в ваших шаблонах. Таким образом, если вы решите изменить сопоставление url в urls.py, вам не нужно обновлять шаблоны :) –