【问题标题】:Using the same form for adding new records and editing existing ones in Django with URL parameter使用相同的表单在 Django 中使用 URL 参数添加新记录和编辑现有记录
【发布时间】:2020-09-01 10:38:30
【问题描述】:

我想使用相同的表单向数据库添加新记录和编辑现有记录。要编辑的记录的 id 是通过 URL 传递的(我应该这样做吗?):

urlpatterns = [
    path('add-or-edit/<int:id>/', add-or-edit_view, name='edit'),
    path('add-or-edit/', add-or-edit_view, name='create'),
[...]

views.py:

def add-or-edit_view(request, id):
    if id is not there: # pseudocode, of course :)
        form = MyForm(request.POST or None)

    elif request.method == "POST":
        obj = get_object_or_404(Event, id=id)
        form = MyForm(request.POST or None, instance=obj)

        if form.is_valid():

            form.save()

    context = {
                'form':form
                }

    return render(request, "templates/add-or-edit.html", context)

换句话说:如果我去 add-or-edit/ 那么我想要我的空表单,如果我去 add-or-edit/1 我想要用来自 id 1 对象的数据填充表单。我我已经在使用两种不同的视图进行此操作,一种是 edit_view(request, id),另一种是 add-or-edit_view(request),当然不是 DRY。

附言

如果我使用:

def event_edit_view(request, id='None'):

    obj = get_object_or_404(Model, id=id)
    form = MyForm(request.POST or None, instance=obj)

如果我访问不带参数的 URL,Django 会报错:

ValueError at /add-or-create/

Field 'id' expected a number but got 'None'.

PS 2

如果我使用:

def add-or-edit_view(request, id='None'):

    if id =='None':
        [unbound form]
    else:
        [bound form]

然后我得到:

AttributeError at /add-or-edit/

'NoneType' object has no attribute 'has_header'

【问题讨论】:

  • 考虑使用位置参数
  • 您能否添加有关“AttributeError at /add-or-edit/ 'NoneType' 对象没有属性 'has_header'”完整堆栈跟踪的更多详细信息

标签: django django-forms django-views django-urls


【解决方案1】:

您可以使用相同的视图,但必须在urls.py 中创建两个条目,然后您才能访问带有或不带有参数的页面(在您的情况下为idexample answer

在视图中你必须这样做:

def add_or_edit_view(request, id=None):
    if id is None:
        # "create view"
        if request.method == 'POST':
            # stuff
        else:
            # other stuff
    else:
        # edit view
        if request.method == 'POST':
            # stuff
        else:
            # other stuff

也不要忘记查看documentation,了解如何处理视图中的表单。

【讨论】:

  • 谢谢。正如您从我的问题中看到的那样,我已经在 url 中有两个指令,并且 'if' 给了我 'NoneType' 对象没有属性 'has_header' 错误。我现在将尝试不带引号的“无”。
  • 但是你让它运行在两个不同的视图和 URL 上?
  • 现在是的,两个视图和两个 url,这就是我要解决的问题,因此我的问题 :) 。我可能必须使用None 而不是'None',稍后再试,谢谢。
  • 我稍微调整了我的答案,使用这种模式你应该能够合并视图然后重构直到你没有重复的代码
  • 看起来很有希望,我只能在明天检查并通知您。
猜你喜欢
  • 1970-01-01
  • 2014-12-28
  • 1970-01-01
  • 2017-05-23
  • 1970-01-01
  • 2013-08-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多