【问题标题】:Why are changes not getting saved to database table when editing objects using django modelform?为什么使用 django modelform 编辑对象时没有将更改保存到数据库表中?
【发布时间】:2017-08-20 11:14:20
【问题描述】:

这是我的第一个 django 应用程序,我正在使用模型表单来更新表中的现有记录。我一直在做一些测试,添加新记录没有任何问题,但是在编辑现有记录时,我的表单似乎表现如预期(我没有收到错误),但更改没有保存。我错过了什么?我已经为此苦苦挣扎了几天,任何帮助将不胜感激。

models.py:

class Mapindex(models.Model):
    COUNTY_CHOICES = (
        ('ALA', 'Alameda'),
        ('CC', 'Contra Costa'),
        ('MRN', 'Marin'),
        ('NAP', 'Napa'),
        ('SCL', 'Santa Clara'),
        ('SF', 'San Francisco'),
        ('SM', 'San Mateo'),
        ('SOL', 'Solano'),
        ('SON', 'Sonoma'),
    )

    ROUTE_CHOICES = (
        ('1', '1'),
        ('4', '4'),
        ('8', '8'),
        ('9', '9'),
        ('12', '12'),
        ('13', '13'),
        ('14', '14'),
        ('17', '17'),
        ('21', '21'),
        ('24', '24'),
        ('25', '25'),
        ('29', '29'),
        ('32', '32'),
        ('35', '35'),
        ('37', '37'),
        ('49', '49'),
        ('52', '52'),
        ('61', '61'),
        ('77', '77'),
        ('80', '80'),
        ('82', '82'),
        ('84', '84'),
        ('85', '85'),
        ('87', '87'),
        ('92', '92'),
        ('93', '93'),
        ('100', '100'),
        ('101', '101'),
        ('102', '102'),
        ('104', '104'),
        ('112', '112'),
        ('113', '113'),
        ('114', '114'),
        ('116', '116'),
        ('117', '117'),
        ('121', '121'),
        ('123', '123'),
        ('128', '128'),
        ('130', '130'),
        ('131', '131'),
        ('141', '141'),
        ('152', '152'),
        ('156', '156'),
        ('160', '160'),
        ('185', '185'),
        ('220', '220'),
        ('221', '221'),
        ('230', '230'),
        ('237', '237'),
        ('238', '238'),
        ('242', '242'),
        ('260', '260'),
        ('262', '262'),
        ('280', '280'),
        ('281', '281'),
        ('380', '380'),
        ('480', '480'),
        ('505', '505'),
        ('580', '580'),
        ('680', '680'),
        ('780', '780'),
        ('880', '880'),
        ('980', '980')

    )

    MAP_DATUMS_CHOICES = (
        ('CCS27Z2E', 'CCS27Z2E'),
        ('CCS27Z2M', 'CCS27Z2M'),
        ('CCS27Z3E', 'CCS27Z3E'),
        ('CCS27Z3M', 'CCS27Z3M'),
        ('CCS27Z4E', 'CCS27Z4E'),
        ('CCS83Z2E', 'CCS83Z2E'),
        ('CCS83Z2M', 'CCS83Z2M'),
        ('CCS83Z3E', 'CCS83Z3E'),
        ('CCS83Z3M', 'CCS83Z3M'),
        ('HARN83Z2E', 'HARN83Z2E'),
        ('HARN83Z2M', 'HARN83Z2M'),
        ('HARN83Z3E', 'HARN83Z3E'),
        ('HARN83Z3M', 'HARN83Z3M'),
        ('LOCAL_E', 'LOCAL_E'),
        ('LOCAL_M', 'LOCAL_M'),
    )

    objectid = models.IntegerField(unique=True, primary_key=True)
    sheetlabel = models.CharField(max_length=8000, blank=True, null=True)
    county = models.CharField(max_length=8000, choices=COUNTY_CHOICES)
    route = models.CharField(max_length=8000, choices=ROUTE_CHOICES)
    pmb = models.CharField(max_length=50, null=True)
    pme = models.CharField(max_length=50, null=True)
    map_sheet_desc = models.CharField(max_length=8000, blank=True, null=True)
    hangingfilegroup = models.CharField(max_length=8000, blank=True, null=True)
    maptype = models.CharField(max_length=8000, blank=True, null=True)
    index_map_filepath = models.CharField(max_length=8000, blank=True, null=True)
    grantor_box_filepath = models.CharField(max_length=8000, blank=True, null=True)
    status = models.CharField(max_length=8000, blank=True, null=True)
    publish = models.CharField(max_length=8000, blank=True, null=True)
    mapdatum = models.CharField(max_length=8000, choices=MAP_DATUMS_CHOICES)
    geo_referenced_datum = models.CharField(max_length=8000, blank=True, null=True)
    mapscale = models.CharField(max_length=8000, blank=True, null=True)
    mapyear = models.CharField(max_length=8000, blank=True, null=True)
    drawingdate = models.CharField(max_length=8000, blank=True, null=True)
    image_path_filename = models.CharField(max_length=8000, blank=True, null=True)
    control_map_filepath = models.CharField(max_length=8000, blank=True, null=True)
    info_sheet_filepath = models.CharField(max_length=8000, blank=True, null=True)
    image_web_path = models.CharField(max_length=300, blank=True, null=True)
    image_web_path_public = models.CharField(max_length=300, blank=True, null=True)
    grantor_box_web_path = models.CharField(max_length=300, blank=True, null=True)
    grantor_box_web_path_public = models.CharField(max_length=300, blank=True, null=True)
    longitude = models.DecimalField(max_digits=38, decimal_places=8, blank=True, null=True)
    latitude = models.DecimalField(max_digits=38, decimal_places=8, blank=True, null=True)
    survey_info_link = models.CharField(max_length=300, blank=True, null=True)
    survey_index_link = models.CharField(max_length=300, blank=True, null=True)
    control_pdf_link = models.CharField(max_length=300, blank=True, null=True)
    is_name = models.CharField(max_length=100, blank=True, null=True)
    is_name_control = models.CharField(max_length=100, blank=True, null=True)
    error_report_path = models.CharField(max_length=300, blank=True, null=True)
    imagefunctions = models.CharField(max_length=300, blank=True, null=True)
    controlimagefunctions = models.CharField(max_length=300, blank=True, null=True)
    centroid_postmile = models.CharField(max_length=50, blank=True, null=True)

    class Meta:
        # managed = False
        db_table = 'mapindex'

forms.py:

from django import forms
from .models import Mapindex

class MapIndexForm(forms.ModelForm):
    class Meta:
        model = Mapindex
        fields = ['objectid', 'image_path_filename', 'county', 'route', 'pmb', 'pme', 'map_sheet_desc', 'drawingdate',
                  'index_map_filepath', 'grantor_box_filepath', 'control_map_filepath', 'info_sheet_filepath', 'mapdatum']

        widgets = {'objectid': forms.HiddenInput()}

        labels = {
            'image_path_filename': 'PDF Filepath',
            'county': 'County',
            'route': 'Route',
            'pmb': 'Begin Postmile',
            'pme': 'End Postmile',
            'map_sheet_desc': 'Map Sheet Description',
            'drawingdate': 'Drawing Date',
            'index_map_filepath': 'Index Map Filepath',
            'grantor_box_filepath': 'Grantor Box Filepath',
            'control_map_filepath': 'Control Map Filepath',
            'info_sheet_filepath': 'Info Sheet Filepath',
            'mapdatum': 'Map Datum'
        }

views.py:

from django.http import request, HttpResponse
from django.shortcuts import render, get_object_or_404
from .models import Mapindex as MapIndexModel
from .forms import MapIndexForm
from django.contrib import messages


def mapindex_edit(request, row_id):
    record = get_object_or_404(MapIndexModel, pk=row_id)
    form_mapindex = MapIndexForm(request.POST or None, instance=record)
    return render(request, 'edit.html', {
                'title': 'Map Index Update Form',
                'form_mapindex': form_mapindex
            })

    if request.method == 'POST' and form_mapindex.isvalid():
        form_mapindex.save()
        return redirect(home)
    context = {'form_mapindex': record}
    return render(request, '/update/')

def saved(request):
    msg = 'Record saved!'
    return HttpResponse(msg)

urls.py:

from django.conf.urls import url
from . import views

urlpatterns = [
    url(r'^$', views.saved, name='saved'),
    url(r'(?P<row_id>[0-9]+)/$', views.mapindex_edit , name='edit'),
]

和模板:

<!DOCTYPE html>             
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
  </head>
  <body>
    <table>
        <thead><th>{{title}}</th>   
    </table>
    <form method="POST" action="/update/">
        <fieldset>
            <legend>Create Map Index Record</legend>
            {% csrf_token %}
            <!-- {{form_mapindex}} -->
             {% for field in form_mapindex.hidden_fields %}
                {{ field }}
                <br>
            {% endfor %}

            {% for field in form_mapindex.visible_fields %}
                {{ field.label_tag }} 
                <br>
                {{ field }}
                <br>
            {% endfor %}

            <br><button type="submit" onclick="window.close()">Save Record</button>
        </fieldset>
        {% if form.errors %}
            {% for field in form %}
                {% for error in field.errors %}
                    <div class="alert alert-danger">
                        <strong>{{ error|escape }}</strong>
                    </div>
                {% endfor %}
            {% endfor %}
            {% for error in form.non_field_errors %}
                <div class="alert alert-danger">
                    <strong>{{ error|escape }}</strong>
                </div>
            {% endfor %}
        {% endif %}
    </form>
  </body>
</html>

【问题讨论】:

  • 当前代码是返回表单的渲染,所以永远无法保存。在你的代码中执行 if request.POST else: 并观察你在上下文中传递的内容和时间
  • 感谢您的回复,我将在 else 语句中添加,但我认为不是这样。你能指出你在第一个陈述中提到的代码吗?我是新手
  • 我用“应该”工作的代码发布了一个答案 :)

标签: django python-2.7 django-models django-forms django-views


【解决方案1】:

因为您的视图在到达保存表单的代码之前返回。

与任何函数一样,一旦返回,就不会再执行该函数中的代码。将返回移动到函数的末尾。

【讨论】:

  • 感谢您的回复,但我不知道这是在哪里发生的?我检查了表格是有效的,所以应该先保存?你能指出错误在哪里吗?是request.method条件上面的return render语句吗?应该去其他地方还是删除?
  • 这是您视图的第三行。实际上没有办法继续检查帖子数据的代码。
  • 还是等一下。您的表单正在发布到 URL“/update/”。这是要去哪里?它根本不在你的 urls.py 中。
  • 我只是希望它在帖子保存后返回到记录已保存的页面,但最终我想在保存记录后关闭窗口。我对如何设置感到困惑。
  • 这没有回答我的任何一个问题。但是您的表单需要发布到实际执行更新的视图,而不是仅打印消息的视图。
【解决方案2】:
def mapindex_edit(request, row_id):
  record = get_object_or_404(MapIndexModel, pk=row_id)
  form_mapindex = MapIndexForm(request.POST or None, instance=record)
  if request.POST:
    if form_mapindex.is_valid():
       form_mapindex.save()
       return redirect(home)

  return render(request, 'edit.html', {
              'title': 'Map Index Update Form',
              'form_mapindex': form_mapindex
          })

应该修复它。

如果表单无效,它将到达第二个返回语句并再次显示表单以及错误(您的模板看起来可以快速浏览)

【讨论】:

  • 注意:重定向语句中的home被假定为链接/有效的url字符串
  • 感谢您的回答,我刚刚尝试过,但不幸的是我的更改仍未保存
  • 实际上主页链接来自我发现的一个sn-p,所以实际上我不知道它指向什么!我还需要那条线吗?
  • 我知道发生了什么,它不符合条件 request.POST.. 为什么不呢?说请求是 GET
  • 你应该使用 POST 保存表单,然后重定向到另一个页面,所以你确实需要重定向,return redirect('/') 将是家。查看 django 消息,我喜欢使用这些消息向会话中添加消息并在重定向后显示。
猜你喜欢
  • 2013-08-19
  • 1970-01-01
  • 2020-05-26
  • 2020-10-11
  • 1970-01-01
  • 2018-10-10
  • 2018-07-07
  • 1970-01-01
相关资源
最近更新 更多