Django 模型窗体

Posted

技术标签:

【中文标题】Django 模型窗体【英文标题】:Django ModelForm 【发布时间】:2011-04-15 11:59:09 【问题描述】:

我正在尝试使用 ModelForm 创建一个简单的 CRUD。它工作正常,除了每次我编辑时,保存都会创建一个新的数据实例。所以我编辑并在 DB 中获得额外的行而不是更新的行。我不知道它如何知道保存现有的慈善机构,因为它不会将 PK(id)存储为表单中的隐藏字段。这就是我在尝试使用“很棒的”模型表单之前总是这样做的!

这让我发疯了,我已经阅读了所有内容,据我所知,我做的一切都是正确的。

这是我的代码..

型号:

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 %

【问题讨论】:

【参考方案1】:

它不起作用,因为您的模板总是发布到添加新 Charity 的视图。当您手动键入 /charities/edit/5 之类的 URL 时,它会使用正确的初始数据创建 ModelForm,但随后会 POST 到 /charities/add,从而创建一个新实例。例如,您需要 POST 到 /charities/edit/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 通用视图,它们在像您这样的简单情况下非常有用。

【讨论】:

您好 Tiago,感谢您的回复。我以前没有听说过 generic_update / create 视图。我会阅读他们的。只是想让现有方法正常工作,我似乎无法从charity.id 中提取ID 以便将其附加到编辑URL。我也尝试了 form.id ,但它不在上下文中。另外,charities_app 是什么?这是你只是放一个占位符让我代替吗?在我的成员视图中,我尝试使用 % url race.members.views.edit member.id % 但出现错误............ Caught ViewDoesNotExist while rendering: Tried home in module race .charities.views. 我愚蠢地忘记了我可以通过上下文传递成员/慈善机构 ID。所以我现在在编辑 URL 中有 ID,它当然可以工作。谢谢。现在我只是想了解如何将操作 URL 替换为类似于您的示例 % url charities_app.views.edit Charities.id % 。什么是charities_app。它应该是视图的路径吗?我需要定义 get_absolute_url 吗? 嗨,在这种情况下 charities_app 将是包含 Charities 模型的应用程序的名称。 charities_app.view.edit 只是要处理请求的视图的名称。这个 url 标签很有用,因为您不必硬连线模板中的 url。这样,如果您选择更改 urls.py 中的 url 映射,则无需更新模板 :)

以上是关于Django 模型窗体的主要内容,如果未能解决你的问题,请参考以下文章

Windows 窗体引用和具有冲突导入类型的单例

C#最基础窗体剖析

ASP.NET Web窗体(.NETFromWork应用程序) ADO.NET 实体数据模型 关于多表联查显示的实现

ASP.NET Web窗体(.NETFromWork应用程序) ADO.NET 实体数据模型 关于多表联查显示的实现

ASP.NET Web窗体(.NETFromWork应用程序) ADO.NET 实体数据模型 关于多表联查显示的实现

从 Web 窗体支架访问 EF 项目 - System.ArgumentNullException