我有一个这样的表格:
{% extends "interface/base.html" %}
{% load subscribertags %}
{% block title %}{{ object }}{% endblock %}
{% block center %}
<div class="page-header">
<h1>Редактирование меню <small>{% operator_name object.operator %}: {{ object }} ({{ object.slug }})</small></h1>
</div>
<!-- Modal -->
<div class="modal fade" id="itemModal" tabindex="-1" role="dialog" aria-labelledby="itemModalTitle" aria-hidden="true">
<form method="post">{% csrf_token %}
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title" id="itemModalTitle">Добавить пункт</h4>
</div>
<div class="modal-body">
<div class="form-group">
<label for="item_name">Действие</label>
<select class="form-control" name="action">
<option value="">----------</option>
{% for value, action in actions %}
<option value="{{ value }}">{{ action }}</option>
{% endfor %}
</select>
</div>
<div class="checkbox">
<label>
<input id='is_hidden' type="checkbox" name='is_hidden' > Спрятать
</label>
</div>
<div class="checkbox">
<label>
<input id='allow_back' type="checkbox" name='allow_back' > Пункт назад
</label>
</div>
<div class="form-group">
<label for="label">Метка</label>
<input type="text" class="form-control" id="label" placeholder="Название метки" name='slug'>
</div>
<div class="form-group">
<label for="params">Доп параметры</label>
<textarea type="text" class="form-control" id="params" placeholder="Дополнительные параметры" name='params'></textarea>
</div>
{% for code, language in languages %}
<div class="form-group">
<h5>{{ language }}</h5>
{% if code = object.default_language %}
<label for="text">Текст</label>
<input type="text" class="form-control" id="text" placeholder="Текст" name='text'>
<label for="result_text">Текст результата</label>
<input type="text" class="form-control" id="result_text" placeholder="Текст результата" name='result_text'>
{% else %}
<label for="text-{{ code }}">Текст</label>
<input type="text" class="form-control" id="text-{{ code }}" placeholder="Текст" name='text-{{ code }}'>
<label for="result_text-{{ code }}">Текст результата</label>
<input type="text" class="form-control" id="result_text-{{ code }}" placeholder="Текст результата" name='result_text-{{ code }}'>
{% endif %}
</div>
{% endfor %}
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Отмена</button>
<button type="subbmit" class="btn btn-primary">Сохранить</button>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</form>
</div><!-- /.modal -->
<div class="tree">
{% if object.item_set.count %}
<ul>
{% with object.item_set.all.0 as item %}
{% include "interactive/interface/menu_item.html" %}
{% endwith %}
</ul>
{% endif %}
</div>
{% endblock %}
SECOND PART:
{% load interactivetags %}
<li class="element-interactive-item{% if not item.is_visible %} i-hidden{% endif %}">
<span data-toggle="tooltip" title="{{ item.params }}" class='name'><i class="glyphicon glyphicon-{% item_icon item %}"></i> ({{ item.id }}) {{ item }} {% if item.slug %}({{ item.slug }}){% endif %}
<a class='tool item-tool' data-values='{% item_to_json item %}' data-toggle="modal" data-target="#itemModal" data-label="Редактировать: {{ item }}" href="#" data-href="{% url "interactive.views.item_update" pk=item.pk %}"><i class="glyphicon glyphicon-edit"></i></a>
<a class='tool item-tool' data-toggle="modal" data-target="#itemModal" data-label="Добавить пункт" href="#" <data-href="{% url "interactive.views.item_create" pk=object.pk parent_pk=item.pk %}"><i class="glyphicon glyphicon-plus"></i></a>
{% if item.is_leaf_node and not item.is_root_node%}
<a class='tool confirm' href="{% url "interactive.views.item_delete" pk=item.pk %}"><i class="glyphicon glyphicon-remove"></i></a>
{% endif %}
<a class='tool confirm' href="{% url "interactive.views.item_up" pk=item.pk %}"><i class="glyphicon glyphicon-arrow-up"></i></a>
<a class='tool confirm' href="{% url "interactive.views.item_down" pk=item.pk %}"><i class="glyphicon glyphicon-arrow-down"></i></a>
</span>
<ul>
{% for item in item.get_children %}
{% include "interactive/interface/menu_item.html" %}
{% endfor %}
</ul>
</li>
当我点击Save /Сохранить按钮时,数据库中没有更新此表单的数据,我得到了
"POST /interactive/1/ HTTP/1.1" 405 0
处理请求的代码:
# -*- coding: utf-8 -*-
from django.core.urlresolvers import reverse
from django.views.generic import ListView, DetailView, CreateView, UpdateView, DeleteView
from django.contrib.contenttypes.models import ContentType
from django.http import HttpResponseRedirect
from interactive.models import Menu, Item
from interactive.forms import UpdateItemForm
from interface.views import InterfaceMixin
from interactive.processors import ProcessorManager
from subscribers.models import Subscriber
from languages.models import Translate
class MenuList(InterfaceMixin, ListView):
model = Menu
name = u'Интерактивные меню'
index = MenuList.as_interface_view(template_name='interactive/interface/index.html')
class MenuItem(InterfaceMixin, DetailView):
""" Редактирование интерактивного меню """
model = Menu
def get_context_data(self, **kwargs):
kwargs['actions'] = ProcessorManager.actions()
kwargs['languages'] = Subscriber.LANGUAGES
return super(MenuItem, self).get_context_data(**kwargs)
menu = MenuItem.as_interface_view(item=MenuList, template_name='interactive/interface/item.html')
class ItemMixin:
@classmethod
def update_language(cls, attribute, text, context):
if text:
o, _ = Translate.objects.get_or_create(attribute=attribute, **context)
o.text = text
o.save()
class CreateItemView(ItemMixin, InterfaceMixin, CreateView):
menu = None
parent = None
model = Item
form_class = UpdateItemForm
auth = False
def get_success_url(self):
return reverse("interactive.views.menu", kwargs={'pk': self.menu.pk})
def post(self, request, *args, **kwargs):
pk = kwargs.get('pk')
parent_pk = kwargs.get('parent_pk')
self.menu = Menu.objects.get(pk=pk)
self.parent = Item.objects.get(pk=parent_pk)
return super(CreateItemView, self).post(request, *args, **kwargs)
def form_valid(self, form):
form.instance.menu = self.menu
form.instance.insert_at(self.parent, position='last-child')
form.instance.save()
ct = ContentType.objects.get_for_model(form.instance)
for code, _ in Subscriber.LANGUAGES:
text = self.request.POST.get('text-%s' % code)
result_text = self.request.POST.get('result_text-%s' % code)
context = dict(content_type=ct, object_id=form.instance.pk, language=code, operator=self.menu.operator)
self.update_language('text', text, context)
self.update_language('result_text', result_text, context)
return super(CreateItemView, self).form_valid(form)
def form_invalid(self, form):
return super(CreateItemView, self).form_valid(form)
item_create = CreateItemView.as_view()
class UpdateItemView(ItemMixin, InterfaceMixin, UpdateView):
""" Изменение пункта меню """
model = Item
form_class = UpdateItemForm
auth = False
def get_success_url(self):
return reverse("interactive.views.menu", kwargs={'pk': self.object.menu.pk})
def form_valid(self, form):
ct = ContentType.objects.get_for_model(self.object)
for code, _ in Subscriber.LANGUAGES:
text = self.request.POST.get('text-%s' % code)
result_text = self.request.POST.get('result_text-%s' % code)
context = dict(content_type=ct, object_id=self.object.pk, language=code)
self.update_language('text', text, context)
self.update_language('result_text', result_text, context)
return super(UpdateItemView, self).form_valid(form)
def form_invalid(self, form):
return super(UpdateItemView, self).form_valid(form)
item_update = UpdateItemView.as_view()
class DeleteItemView(InterfaceMixin, DeleteView):
model = Item
auth = False
def get_success_url(self):
return reverse("interactive.views.menu", kwargs={'pk': self.object.menu.pk})
def get(self, request, *args, **kwargs):
return self.delete(request, *args, **kwargs)
item_delete = DeleteItemView.as_view()
class UpDownItemVew(DetailView):
action = None
model = Item
auth = False
def get(self, request, *args, **kwargs):
item = self.get_object()
if self.action == 'left':
other = item.get_previous_sibling()
else:
other = item.get_next_sibling()
item.move_to(other, position=self.action)
return HttpResponseRedirect(reverse("interactive.views.menu", kwargs={'pk': item.menu.pk}))
item_up = UpDownItemVew.as_view(action='left')
item_down = UpDownItemVew.as_view(action='right')
网址格式:
urlpatterns = patterns(
'interactive.views',
(r'^(?P<pk>\d+)/(?P<parent_pk>\d+)/additem/$', "item_create"),
(r'^item/(?P<pk>\d+)/delete/$', "item_delete"),
(r'^item/(?P<pk>\d+)/up/$', "item_up"),
(r'^item/(?P<pk>\d+)/down/$', "item_down"),
(r'^item/(?P<pk>\d+)/$', "item_update"),
(r'^(?P<pk>\d+)/$', "menu"),
(r'^$', 'index'),
)
此代码完全适用于生产服务器,但我没有上传,并使用nginx作为http服务器。
我使用python manage.py runserver