Django modelformset_factory什么都不保存

时间:2017-08-25 12:05:50

标签: python django django-forms

为简单模型创建了一组表单。当我尝试更改表单中的模型对象数据并将这些更改保存在数据库中时,新数据不会作为结果保存,并且会重定向到具有相同数据的表单页面,尽管至少有关于应输出成功或失败的操作。终端不会返回任何错误,它会在日志中写入正确的请求发送,测试服务器在正常模式下不会丢失。有一种观点认为,其原因是拒绝验证,但出于何种原因发生这种情况以及隐藏错误的地方,尚无法理解。

当我点击"保存"按钮,在终端中看到此消息(见下文):

  

[25 / Aug / 2017 18:03:06]" GET   /类别/ csrfmiddlewaretoken = igSZl3z8pcF9qRGaMts9hG3T9dyaIpVvAxB672R34bmKvGYd6pymjmtwyEgDHGg2&安培;形状TOTAL_FORMS = 6&安培;形状INITIAL_FORMS = 5&安培;形状MIN_NUM_FORMS = 0&安培;形状MAX_NUM_FORMS = 1000&安培;形式-0-ID = 1和;形式-O-名称= fhdrhddh&安培;形状配合0级= 0&安培;形式-1-ID = 2及形式-1-名称= gdegasf&安培;形式-1阶= 6&安培;形式-2-ID = 3及形式-2-名称= dfdgbsbgsdgs&安培;形式-2-为了= 2及形式-3-ID = 4和;形式-3-名称= dbgsgbasedgbaedvg&安培;形式-3-顺序= 3及形式-4-ID = 5&安培;形式-4-名称= dgfsdg3waesdvz&安培;形式-4-顺序= 4安培;形式-5-ID =&安培;形式-5-名称=安培;形式-5-顺序= 0   HTTP / 1.1" 200 7502

models.py(应用类别)

from django.db import models

# Create your models here.

class Category(models.Model):
    name = models.CharField(max_length = 30, db_index = True, unique = True, verbose_name = "Title")
    order = models.PositiveSmallIntegerField(default = 0, db_index = True, verbose_name = "Serial number")
    def __str__(self):
        return self.name
    class Meta:
        ordering = ["order", "name"]
        verbose_name = "category"
        verbose_name_plural = "categories"

views.py(类别应用)

from django.views.generic.base import TemplateView
from django.forms.models import modelformset_factory
from django.shortcuts import redirect
from django.contrib import messages
from categories.models import Category
from generic.mixins import CategoryListMixin

CategoriesFormset = modelformset_factory(Category, can_delete=True, fields = '__all__', extra=1, max_num=None)

class CategoriesEdit(TemplateView, CategoryListMixin):
    template_name = "categories_edit.html"
    formset = None
    def get(self, request, *args, **kwargs):
        self.formset = CategoriesFormset()
        return super(CategoriesEdit, self).get(request, *args, **kwargs)
    def get_context_data(self, **kwargs):
        context = super(CategoriesEdit, self).get_context_data(**kwargs)
        context["formset"] = self.formset
        return context
    def post(self, request, *args, **kwargs):
        self.formset = CategoriesFormset(request.POST)
        if self.formset.is_valid():
            self.formset.save()
            messages.api.add_message(request, messages.SUCCESS, "List of categories successfully changed")
            return redirect("categories_edit")
        else:
            messages.api.add_message(request, messages.SUCCESS, "Something is wrong!!!")
            return super(CategoriesEdit, self).get(request, *args, **kwargs)

mixins.py

from django.views.generic.base import ContextMixin

class CategoryListMixin(ContextMixin):
    def get_context_data(self, **kwargs):
        context = super(CategoryListMixin, self).get_context_data(**kwargs)
        context["current_url"] = self.request.path
        return context

categories_edit.html(类别应用)

{% extends "categories_base.html" %}
{% block title %} Categories {% endblock %}
{% block main %}
    {% include "generic/messages.html" %}
    {{ formset.errors }}
    <h2>Categories</h2>
    <form action="" method="post">
        {% include "generic/formset.html" %}
        <div class="submit-button"><input type="submit" value="Save"></div>
    </form>
{% endblock %}

formset.html(类别应用)

{% csrf_token %}
{{ formset.management_form }}
<table class="form">
    <tr>
        <th></th>
        {% with form=formset|first %}
            {% for field in form.visible_fields %}
                <th>
                    {{ field.label }}
                    {% if field.help_text %}
                        <br>{{ field.help_text }}
                    {% endif %}
                </th>
            {% endfor %}
        {% endwith %}
    </tr>
    {% for form in formset %}
        <tr>
            <td>
                {% for field in form.hidden_fields %}
                    {{ field }}
                {% endfor %}
            </td>
            {% for field in form.visible_fields %}
                <td>
                    {% if field.errors.count > 0 %}
                        <div class="error-list">
                            {{ field.errors }}
                        </div>
                    {% endif %}
                    <div class="control">{{ field }}</div>
                </td>
            {% endfor %}
        </tr>
    {% endfor %}
</table>

messages.html(类别应用)

{% if messages %}
    <div id="messages-list">
        {% for message in messages %}
            <p class="{{ message.tags }}">{{ message }}</p>
        {% endfor %}
    </div>
{% endif %}

urls.py(类别应用)

from django.conf.urls import url
from django.contrib.auth.decorators import login_required
from categories.views import CategoriesEdit

urlpatterns = [
    url(r'^$', login_required(CategoriesEdit.as_view()), name  = "categories_edit"),
]

settings.py(项目)

"""
Django settings for t****** project.

Generated by 'django-admin startproject' using Django 1.10.6.

For more information on this file, see
https://docs.djangoproject.com/en/1.10/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.10/ref/settings/
"""

import os

BASE_DIR = os.path.dirname(os.path.dirname(__file__))

# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.10/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = '***************************************************'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = []


# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'guestbook',
    'categories',
    'imagepool',
    'page',
    'main',
    'news',
    'shop',
    'django.contrib.sites',
    'django_comments',
    'easy_thumbnails',
    'taggit',
    'precise_bbcode',
]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

ROOT_URLCONF = 't******.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

WSGI_APPLICATION = 'tdkennel.wsgi.application'


# Database
# https://docs.djangoproject.com/en/1.10/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 't******l',
        'USER': 'p*******',
        'PASSWORD': '********',
        'HOST': '',
        'PORT': '5432',
    }
}

# Password validation
# https://docs.djangoproject.com/en/1.10/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]


# Internationalization
# https://docs.djangoproject.com/en/1.10/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_L10N = True

USE_TZ = True


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.10/howto/static-files/

STATIC_URL = '/static/'
STATICFILES_DIRS = (os.path.join(BASE_DIR, 'static'),)

MEDIA_ROOT = os.path.join(BASE_DIR, 'upload')
MEDIA_URL = '/media/'

LOGIN_URL = "login"
LOGOUT_URL = "logout"

SITE_ID = 1

THUMBNAIL_BASEDIR = "thumbnails"
THUMBNAIL_BASEDIR = {"goods.Good.image": {"base": {"size": (200, 100)},},}

LOGIN_REDIRECT_URL = "main"

2 个答案:

答案 0 :(得分:0)

我记得有类似事情发生在我身上。我最终使用Form来创建Formset

尝试:

from django.forms import ModelForm
from categories.models import Category
from django.forms.models import modelformset_factory

class CategoryForm(ModelForm):
    class Meta:
        model = Category
        fields = '__all__'

CategoryFormSet = modelformset_factory(Category, form=CategoryForm)

并在CategoryFormSet

中使用CategoriesEdit

这只是一种解决方法,但希望这会有所帮助!

答案 1 :(得分:0)

我的疏忽是我的错。我在categories_edit.html(在我的项目中)的代码的注释和连接部分写了method =“post”,忘了用未注释的代码片写出来:

   {# <form method="post" action=""> #}
    <form method="" action="">
        {% include "generic/formset.html" %}
        {# {% csrf_token %} #}
        {# {{ formset.as_p }} #}
        <div class="submit-button"><input type="submit" value="Save"></div>
    </form>

但我混淆了用户,因为在我的问题中写了一切都是正确的,而不是删除代码的连接部分并输入正确的代码段:

    <form method="post" action="">
        {% include "generic/formset.html" %}
        {# {% csrf_token %} #}
        {# {{ formset.as_p }} #}
        <div class="submit-button"><input type="submit" value="Save"></div>
    </form>

我向回答我问题的用户道歉!代码工作。