Django - 405 POST not allowed - django

I have a form like so:
{% 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>
When I hit the Save/Сохранить button data isn't updated in the database for this form and I get
"POST /interactive/1/ HTTP/1.1" 405 0
Code that handles the request:
# -*- 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')
URL patterns:
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'),
)
This code perfectly work on a production server, but wasn't uploaded by me and uses nginx as http server.
I am running it on local server using python manage.py runserver

Related

using class base view facing a issue of reverse not found

i am using a class base d view for section.html in which i trying to implement add to cart functionality with the help of forms but after clicking add to car but it showing error
Reverse for 'section' with no arguments not found. 1 pattern(s) tried: ['(?P<subject_id>[0-9]+)/Sections/$']
here is my views.py
#method_decorator(login_required, name='dispatch')
class Sections(View):
def post(self, request, subject_id):
sections =request.POST.get('section')
print(sections)
return redirect('subjects:section')
def get(self, request, subject_id):
subject = get_object_or_404(Subject, pk=subject_id) # retrieve the subject
sections = subject.section.all() # get the sections related to the subject
return render (request, 'sections.html',{"section_list" : sections })
my urls.py
urlpatterns = [
path('<int:subject_id>/Sections/', Sections.as_view(),name='section'),
]
my section.html
<ul class="sec">
{% for section in section_list %}
<div class="card col-11">
<div class="card-header">
{{ section.title }}
</div>
<div class="card-body">
<h5 class="card-about">{{ section.about_section }}</h5> <br>
<i class="price fas fa-rupee-sign"> {{ section.price }}</i> <br> <br>
<i class="icon text-white fas fa-chalkboard-teacher"> {{ section.teacher }}</i>
<i class="icon text-white fas fa-clock"> {{ section.content_duration}}</i>
<i class="icon text-white fas fa-tags"> {{ section.subject.name }}</i>
<form action="#" method="POST">
{% csrf_token %}
<input hidden type="text" name="section" value="{{section.id}}">
<input type="submit" class="btn btn-outline-primary" value="Add To Cart">
</form>
</div>
</div>
{% endfor %}
</ul>
my section model is contected with another models name subject with foriegn key
You have to specify a subject_id to redirect since you have a <int:subject_id> in the path and the get method requires it.
#method_decorator(login_required, name='dispatch')
class Sections(View):
def post(self, request, subject_id):
sections =request.POST.get('section')
print(sections)
return redirect('subjects:section', subject_id=subject_id)

Django Handling Multiple Forms

I'm currently working on To-Do App using Django.
I got stucked in handling two different forms in single html file and each form has separate function in views. I have two models Todo and Task.
The task items should be placed under to-do item. In short To-Do is a Category and the task's are its sub-category. The data is not getting saved and displayed in the Web.
I have two forms in main.html one is for to-do item and other one is for task item. Each have two different function in views.py which are home and add_todo function respectively.
In form-2 which is for task item built using bootstrap Modal. The form action provided to add_todo function in views.py.
models.py
class Todo(models.Model):
date_created = models.DateTimeField(auto_now_add=True)
completed = models.BooleanField(default=False)
title = models.CharField(max_length=200)
user_id = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
def __str__(self):
return self.title
class Task(models.Model):
heading = models.CharField(max_length=100)
todo = models.ForeignKey(Todo, on_delete=models.CASCADE, related_name='tasks')
date_created = models.DateTimeField(auto_now_add=True)
completed = models.BooleanField(default=False)
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
def __str__(self):
return self.heading
views.py
from django.shortcuts import render, redirect, get_object_or_404
from django.http import HttpResponse, Http404, HttpResponseNotFound, JsonResponse, HttpResponseRedirect
from .models import Todo, Task
from .forms import *
from django.utils import timezone
from django.contrib.auth.forms import UserCreationForm
from django.views.decorators.csrf import csrf_protect
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.decorators import login_required
from django.views.generic import View
from django.contrib.auth.models import User
from django.core.paginator import Paginator
def register(request):
form = userRegisterForm()
if request.method == 'POST':
form = userRegisterForm(request.POST)
if form.is_valid():
form.save()
username = form.cleaned_data.get('username')
password = form.cleaned_data.get('password2')
return redirect('login')
else:
form = userRegisterForm()
context = {'form': form}
return render(request, 'todo/register.html', context)
def logoutUser(request):
logout(request)
return redirect('login')
#login_required(login_url='login')
def home(request):
todo_form = TodoForm()
task_form = TaskForm()
current = timezone.now()
todo_items_upcoming = Todo.objects.filter(user_id=request.user, completed=False).order_by('-date_created')
todo_items_completed = Todo.objects.filter(user_id=request.user, completed=True).order_by('-date_created')
pagi1 = Paginator(todo_items_upcoming, 4)
pagi2 = Paginator(todo_items_completed, 4)
page_num = request.GET.get('upcoming', 1)
page_num2 = request.GET.get('completed', 1)
page_obj = pagi1.get_page(page_num)
page_obj2 = pagi2.get_page(page_num2)
if request.method == "POST":
todo_form1 = TodoForm(request.POST)
if todo_form1.is_valid():
data = todo_form1.cleaned_data.get('title')
obj = Todo.objects.create(date_created=current, title=data, user_id=request.user)
return redirect('/')
context = {'todo_form': todo_form, 'page_obj': page_obj, 'page_obj2': page_obj2,
'pagi1': pagi1, 'pagi2': pagi2, 'page_num2': int(page_num2), 'page_num': int(page_num), 'task_form':task_form}
return render(request, 'todo/main.html', context)
#login_required(login_url='login')
def update_todo(request, pk):
try:
obj = Todo.objects.get(id=pk, user_id=request.user)
upform = TodoForm(instance=obj)
if request.method == 'POST':
upform = TodoForm(request.POST, instance=obj)
if upform.is_valid():
upform.save()
return redirect('/')
except Exception as err:
try:
obj = Task.objects.get(id=pk, user=request.user)
upform = TaskForm(instance=obj)
if request.method == 'POST':
upform = TaskForm(request.POST, instance=obj)
if upform.is_valid():
upform.save()
return redirect('/')
except Exception as err:
raise Http404(err)
context = {'upform': upform}
return render(request, 'todo/update_task.html', context)
#login_required(login_url='login')
def add_todo(request, pk):
try:
obj = Todo.objects.get(id=pk, user_id=request.user)
except Exception as e:
raise Http404(e)
if request.method == 'POST':
t_form = TaskForm(request.POST)
if t_form.is_valid():
data = t_form.cleaned_data.get('heading')
Task.objects.create(user=request.user, heading=data, todo=obj, date_created=timezone.now())
return redirect('/')
else:
t_form = TaskForm()
context = {'t_form':t_form}
return render(request, 'todo/main.html', context)
#login_required(login_url='login')
def delete_todo(request, pk):
try:
obj = Todo.objects.get(id=pk, user_id=request.user)
except Exception as err:
try:
obj = Task.objects.get(id=pk, user=request.user)
except Exception as err:
raise Http404(err)
obj.delete()
return HttpResponseRedirect(request.META.get('HTTP_REFERER'))
#login_required(login_url='login')
def completed_todo(request, pk):
try:
obj = Todo.objects.get(id=pk, user_id=request.user)
except Exception as err:
try:
obj = Task.objects.get(id=pk, user=request.user)
except Exception as err:
raise Http404(err)
obj.completed = True
obj.save()
# return redirect('/')
return HttpResponseRedirect(request.META.get('HTTP_REFERER'))
main.html
{% extends 'todo/index.html' %}
{% load crispy_forms_tags %}
{% block content %}
<div class="center-column">
<h5 class="card-title">Create your List</h5>
#form-1
<form action="" method="POST">
{% csrf_token %}
<div class="input-group-append">
{{ todo_form.title }}
<button type="submit" class="form-control btn btn-primary mb-3 mr-sm-2" id="addItem">
Add Items
</button>
</div>
</form>
</div>
<div class="row">
<div class="col-sm-6">
<div class="card">
<div class="card-body">
<h4 class="card-title">Upcoming Items</h4>
<hr/>
<ul class="list-group" id="upcomingItems">
{% for i in page_obj %}
<li class="list-group-item list-group-item-primary mb-1" id="upcomingItem">
{{ i.title }}
<div class="float-right">
<button type="submit" class="btn btn-sm btn-danger ml-1 mt-1 mr-1 mb-1">
❌
</button>
</div>
<div class="float-right">
<button type="submit" class="btn btn-sm btn-success ml-1 mt-1 mr-1 mb-1" id="update_btn">
Update
</button>
</div>
<div class="float-right">
<button type="submit" class="btn btn-sm btn-dark ml-1 mt-1 mr-1 mb-1" id="completed_btn">
Completed
</button>
</div>
<div class="float-right">
<!-- Button trigger modal -->
<button type="button" class="btn btn-sm btn-primary ml-1 mt-1 mr-1 mb-1" data-toggle="modal" data-target="#staticBackdrop">
Add
</button>
<!-- Modal -->
<div class="modal fade" id="staticBackdrop" data-backdrop="static" tabindex="-1" role="dialog" aria-labelledby="staticBackdropLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="staticBackdropLabel">Add New Task</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
#form-2
<form action="{% url 'home' %}" method="POST">
{% csrf_token %}
<div class="card">
{{ task_form.heading }}
</div>
<div class="modal-footer">
<button class="btn btn-success" type="submit">Submit</button>
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
{% for j in i.tasks.all %}
{% if i.tasks.all %}
<div class="card mt-4">
<ul class="list-group">
<li class="list-group-item list-group-item-danger" id="upcomingItem">
{{ j.heading }}
<div class="float-right">
<button type="submit" class="btn btn-sm btn-danger ml-1 mt-1 mr-1 mb-1">
❌
</button>
</div>
<div class="float-right">
<button type="submit" class="btn btn-sm btn-dark ml-1 mt-1 mr-1 mb-1" id="completed_btn">
Completed
</button>
</div>
</li>
</ul>
</div>
{% endif %}
{% endfor %}
</li>
{% endfor %}
</ul>
<hr/>
<ul class="pagination justify-content-center">
{% if page_obj.has_previous %}
<li class="page-item {% if page_obj.page_number == page_num %} active {% endif %}">
<a class="page-link" href="?upcoming={{ page_obj.previous_page_number }}&completed={{ page_num2 }}">&laquo</a>
</li>
{% endif %}
{% for i in pagi1.page_range %}
<li class="page-item {% if i == page_num %} active {% endif %}">
<a class="page-link" href="?upcoming={{ i }}&completed={{ page_num2 }}">{{ i }}</a>
</li>
{% endfor %}
{% if page_obj.has_next %}
<li class="page-item {% if page_obj.page_number == page_num %} active {% endif %}">
<a class="page-link" href="?upcoming={{ page_obj.next_page_number }}&completed={{ page_num2 }}">&raquo</a>
</li>
{% endif %}
</ul>
</div>
</div>
</div>
<div class="col-sm-6">
<div class="card">
<div class="card-body">
<h4 class="card-title">Completed Items</h4>
<hr/>
<ul class="list-group">
{% for i in page_obj2 %}
{% if not i.tasks.all %}
<li class="list-group-item list-group-item-primary mb-1" id="upcomingItem">
{{ i.title }}
<div class="float-right">
<button type="submit" class="btn btn-sm btn-danger mt-1 mb-1">
❌
</button>
</div>
</li>
{% else %}
{% for j in i.tasks.all %}
<li class="list-group-item list-group-item-primary mb-1" id="upcomingItem">
{{ i.title }}
<div class="float-right">
<button type="submit" class="btn btn-sm btn-danger mt-1 mb-1">
❌
</button>
</div>
<div class="card mt-4">
<ul class="list-group">
<li class="list-group-item list-group-item-danger">
{{ j.heading }}
<div class="float-right">
<button type="submit" class="btn btn-sm btn-danger">
❌
</button>
</div>
</li>
</ul>
</div>
</li>
{% endfor %}
{% endif %}
{% endfor %}
</ul>
<hr/>
<ul class="pagination justify-content-center">
{% if page_obj2.has_previous %}
<li class="page-item {% if page_obj2.page_number == page_num %} active {% endif %}">
<a class="page-link" href="?completed={{ page_obj2.previous_page_number }}&upcoming={{ page_num }}">&laquo</a>
</li>
{% endif %}
{% for i in pagi2.page_range %}
<li class="page-item {% if i == page_num2 %} active {% endif %}">
<a class="page-link" href="?completed={{ i }}&upcoming={{ page_num }}">{{ i }}</a>
</li>
{% endfor %}
{% if page_obj2.has_next %}
<li class="page-item {% if page_obj2.page_number == page_num %} active {% endif %}">
<a class="page-link" href="?completed={{ page_obj2.next_page_number }}&upcoming={{ page_num }}">&raquo</a>
</li>
{% endif %}
</ul>
</div>
</div>
</div>
</div>
{% endblock %}
forms.py
class TodoForm(forms.ModelForm):
class Meta:
model = Todo
fields = ['title', 'completed']
class TaskForm(forms.ModelForm):
class Meta:
model = Task
fields = ['heading', 'todo', 'completed']
class userRegisterForm(UserCreationForm):
email = forms.EmailField()
class Meta:
model = User
fields = ['username','email','password1','password2']
urls.py
urlpatterns = [
path('', views.home, name='home'),
path('update_todo/<int:pk>/', views.update_todo, name='update_todo'),
path('completed/<int:pk>/', views.completed_todo, name="completed_todo"),
path('delete_todo/<int:pk>/', views.delete_todo, name='delete_todo'),
path('add_todo/<int:pk>/', views.add_todo, name='addTodo'),
path('register/', views.register, name='register'),
path('login/', auth_views.LoginView.as_view(template_name='todo/login.html'), name='login'),
path('logout/', auth_views.LogoutView.as_view(template_name='todo/logout.html'), name='logout'),
]
When I click Add button and type something and click enter, the data was not saved in the DB so that I'm unable to see the tasks data.
Image-1
Task form Popup modal using bootstrap for adding task items under a todo.
Image-2
Whenever I add task items for other todo items, those task items are getting dtored to 1t todo items not to their corresponding todo items. I have added two task items on Maths Todo items but those Maths-1 and Maths-2 was created under 1st todo items.
Simple way is
action = "{%url 'link_name' %}"
You can specify the function path name in the form Action.
The changes I have made are in add_todo function and bootstrap modal form.
views.py ad_todo function
def add_todo(request, pk):
obj = Todo.objects.get(id=pk, user_id=request.user)
if request.method == 'POST':
if request.POST.get('heading'):
data = Task()
data.heading = request.POST.get('heading')
data.todo = obj
data.user = request.user
data.save()
return redirect('/')
In main.html file - form-2 which is a bootstrap Modal form for adding task items.
<div class="float-right">
<!-- Button trigger modal -->
<button type="button" class="btn btn-sm btn-primary ml-1 mt-1 mr-1 mb-1">
<a href="{% url 'addTodo' i.id %}" data-toggle="modal" data-target="#staticBackdrop">
Add
</a>
</button>
<!--Modal -->
<div class="modal fade" id="staticBackdrop" data-backdrop="static" tabindex="-1" role="dialog" aria-labelledby="staticBackdropLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="staticBackdropLabel">Add New Task</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<form action="{% url 'addTodo' i.id %}" method="POST">
{% csrf_token %}
<div class="card">
{{ task_form.heading }}
</div>
<div class="modal-footer">
<button class="btn btn-success" type="submit">Submit</button>
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>

Merge Login and Signup into one view in django

Merging login/signup view into one view, say LoginSignupView because I have login, signup form in one template.
I refered https://gist.github.com/jamesbrobb/748c47f46b9bd224b07fbut think that it doesn't work (Actually I don't know how it works)
My views.py :
from django.views.generic.base import ContextMixin, TemplateResponseMixin
from django.views.generic.edit import ProcessFormView
from django.http.response import HttpResponseRedirect, HttpResponseForbidden
from django.contrib.auth.forms import AuthenticationForm
from users.forms import MyUserCreationForm
class MultiFormMixin(ContextMixin):
form_classes = {}
prefixes = {}
success_urls = {}
grouped_forms = {}
initial = {}
prefix = None
success_url = None
def get_form_classes(self):
return self.form_classes
def get_forms(self, form_classes, form_names=None, bind_all=False):
return dict([(key, self._create_form(key, klass, (form_names and key in form_names) or bind_all)) \
for key, klass in form_classes.items()])
def get_form_kwargs(self, form_name, bind_form=False):
kwargs = {}
kwargs.update({'initial':self.get_initial(form_name)})
kwargs.update({'prefix':self.get_prefix(form_name)})
if bind_form:
kwargs.update(self._bind_form_data())
return kwargs
def forms_valid(self, forms, form_name):
form_valid_method = '%s_form_valid' % form_name
if hasattr(self, form_valid_method):
return getattr(self, form_valid_method)(forms[form_name])
else:
return HttpResponseRedirect(self.get_success_url(form_name))
def forms_invalid(self, forms):
return self.render_to_response(self.get_context_data(forms=forms))
def get_initial(self, form_name):
initial_method = 'get_%s_initial' % form_name
if hasattr(self, initial_method):
return getattr(self, initial_method)()
else:
return self.initial.copy()
def get_prefix(self, form_name):
return self.prefixes.get(form_name, self.prefix)
def get_success_url(self, form_name=None):
return self.success_urls.get(form_name, self.success_url)
def _create_form(self, form_name, klass, bind_form):
form_kwargs = self.get_form_kwargs(form_name, bind_form)
form_create_method = 'create_%s_form' % form_name
if hasattr(self, form_create_method):
form = getattr(self, form_create_method)(**form_kwargs)
else:
form = klass(**form_kwargs)
return form
def _bind_form_data(self):
if self.request.method in ('POST', 'PUT'):
return{'data': self.request.POST,
'files': self.request.FILES,}
return {}
class ProcessMultipleFormsView(ProcessFormView):
def get(self, request, *args, **kwargs):
form_classes = self.get_form_classes()
forms = self.get_forms(form_classes)
return self.render_to_response(self.get_context_data(forms=forms))
def post(self, request, *args, **kwargs):
form_classes = self.get_form_classes()
form_name = request.POST.get('action')
if self._individual_exists(form_name):
return self._process_individual_form(form_name, form_classes)
elif self._group_exists(form_name):
return self._process_grouped_forms(form_name, form_classes)
else:
return self._process_all_forms(form_classes)
def _individual_exists(self, form_name):
return form_name in self.form_classes
def _group_exists(self, group_name):
return group_name in self.grouped_forms
def _process_individual_form(self, form_name, form_classes):
forms = self.get_forms(form_classes, (form_name,))
form = forms.get(form_name)
if not form:
return HttpResponseForbidden()
elif form.is_valid():
return self.forms_valid(forms, form_name)
else:
return self.forms_invalid(forms)
def _process_grouped_forms(self, group_name, form_classes):
form_names = self.grouped_forms[group_name]
forms = self.get_forms(form_classes, form_names)
if all([forms.get(form_name).is_valid() for form_name in form_names.values()]):
return self.forms_valid(forms)
else:
return self.forms_invalid(forms)
def _process_all_forms(self, form_classes):
forms = self.get_forms(form_classes, None, True)
if all([form.is_valid() for form in forms.values()]):
return self.forms_valid(forms)
else:
return self.forms_invalid(forms)
class BaseMultipleFormsView(MultiFormMixin, ProcessMultipleFormsView):
"""
A base view for displaying several forms.
"""
class MultiFormsView(TemplateResponseMixin, BaseMultipleFormsView):
"""
A view for displaying several forms, and rendering a template response.
"""
class LoginSignupView(MultiFormsView):
template_name = 'users/login_signup.html'
form_classes = {'login': AuthenticationForm,
'signup': MyUserCreationForm}
success_url = '/'
def get_login_initial(self):
return {'email':'dave#dave.com'}
def get_signup_initial(self):
return {'email':'dave#dave.com'}
def get_context_data(self, **kwargs):
context = super(LoginSignupView, self).get_context_data(**kwargs)
context.update({"some_context_value": 'blah blah blah',
"some_other_context_value": 'blah'})
return context
def login_form_valid(self, form):
return form.login(self.request, redirect_url=self.get_success_url())
def signup_form_valid(self, form):
user = form.save(self.request)
return form.signup(self.request, user, self.get_success_url())
template : login_signup.html
{% extends 'chacha_dabang/skeleton/base.html' %}
{% load pipeline%}
{% block content %}
<div class="container">
<div id="loginbox" class="mainbox">
<div class="panel panel-info">
<div class="panel-heading">
<div class="panel-title">Sign In</div>
</div>
<div class="panel-body">
<div id="login-alert" class="alert alert-danger col-sm-12"></div>
<form id="loginform" class="form-horizontal" role="form" method="post" action="{% url 'users:login_signup' %}">
{% csrf_token %}
<!-- id / pw -->
<div class="input-group">
<span class="input-group-addon"><i class="icon-user"></i></span>
<input id="id_username" type="text" class="form-control" name="username" value="" placeholder="username">
</div>
<div class="input-group">
<span class="input-group-addon"><i class="icon-lock"></i></span>
<input id="id_password" type="password" class="form-control" name="password" placeholder="password">
</div>
<div class="form-group">
<!-- Button -->
<div class="btn-controls">
<div class="row">
<input id="btn-login" class="btn btn-success" type="submit" name="login_submit" value="로 그 인" />
<a id="btn-fblogin" href="{% url 'social:begin' backend='facebook' %}" class="btn btn-primary col-xs-12"><i class="icon-facebook"></i> 1초만에 페이스북으로 로그인 </a>
</div>
</div>
</div>
<div class="form-group">
<div class="col-md-12 control">
<div class="signup">
아직 차차다방 회원이 아니세요? &nbsp
가입하기
</div>
<div class="forget">
비밀번호를 잊어버리셨나요?
</div>
</div>
</div>
</form>
</div> <!-- <div class="panel-body" > -->
</div> <!-- <div class="panel panel-info"> -->
</div> <!-- <div id="loginbox"> -->
<!-- Sign up Form -->
<div id="signupbox" class="mainbox">
<div class="panel panel-info">
<div class="panel-heading">
<div class="panel-title">Sign Up</div>
</div>
<div class="panel-body">
<form id="signupform" class="form-horizontal" role="form" method="post" action="{% url 'users:login_signup' %}">
{% csrf_token %}
<!-- signup -->
<div id="signupalert" class="alert alert-danger">
<p>Error:</p>
<span></span>
</div>
{{ forms.signup.as_p }}
<!--
<div class="form-group">
<label for="id_username" class="col-md-3 control-label"> 아이디: </label>
<div class="col-md-9">
{{ form.username }}
</div>
</div>
-->
<div class="form-group">
<!-- Button -->
<div class="btn-controls">
<div class="row">
<input id="btn-signup" class="btn btn-success" type="submit" name="signup_submit" value="가 입 하 기" />
<a id="btn-fblogin" href="{% url 'social:begin' backend='facebook' %}" class="btn btn-primary col-xs-12"><i class="icon-facebook"></i>1초만에 페이스북으로 로그인</a>
</div>
</div>
</div>
<div class="form-group">
<div class="col-md-12 control">
<div class="login">
이미 차차다방 회원이신가요? &nbsp
로그인하기
</div>
</div>
</div>
</form>
</div> <!-- <div class="panel-body"> -->
</div> <!-- <div class="panel panel-info"> -->
</div> <!-- <div id="signupbox"> -->
</div> <!-- <div class="container"> -->
{% endblock %}
{% block custom_js %}
{% javascript "account" %}
{% endblock %}
First, I test creating user (signup) but when I submit the button, it doesn't create new user.
What am I missing?
Your code is too much to go through, and has a lot of lines for a simple challenge. There are many options.
Create custom views instead of using Form Mixins. They would be a lot easier to write and understand. Identify the form submitted by a hidden input in each form.
Create 2 views using the Mixins, each for login and signup and modify the action part of your forms to submit to the correct view respectively.
Hope it helps.

Crispy-forms form.name renders rubbish

I'm trying to render a form but the {{form.name}} renders rubbish. The problem is that I can't even debug this to figure where the thing gets crooked.
The form:
class ActionItemForm(forms.ModelForm):
class Meta:
model = ActionItem
fields = ('project', 'portfolio', 'name', 'description', 'resolution', 'parent', 'priority', 'status', 'assignee', 'due_date')
def __init__(self, *args, **kwargs):
self.helper = FormHelper()
self.helper.form_tag = False
self.helper.layout = Layout()
super(ActionItemForm, self).__init__(*args, **kwargs)
The view:
def action_item_actions(request, action_item_id, action_code):
def enrich_form(wf_item, form):
form.id = 'edit_action_item'
form.name = form.id
form.title = wf_item.name
form.action = '/forms/action_item/edit/%s' % action_item_id
return form
action_item = ActionItem.objects.get(id=action_item_id)
wf_item = action_item.wf_get_action_by_code(action_code)
if wf_item:
if wf_item.trans_to:
form = ActionItemForm(instance=action_item, initial={action_item.get_wf_field(): type(getattr(action_item, action_item.get_wf_field())).objects.get(id=wf_item.trans_to)})
else:
form = ActionItemForm(instance=action_item)
form = enrich_form(wf_item, form)
for field in form.Meta.fields:
if field not in wf_item.fields:
form.helper.layout.fields.append(Field(field, type='hidden'))
return render_to_response('forms/modal_form.html', {'form': form}, template.RequestContext(request))
else:
return render_to_response('forms/message.html', {'message': Message('Error', 'WF Descriptor not found')}, template.RequestContext(request))
When the form exists the view, the form.name is correct:
Now when the form enters the template, it's still ok:
The view is quite simple:
{% load crispy_forms_tags %}
<form id="{{ form.id }}" role="form" class="small" name="{{ form.name }}">
<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="myModalLabel">{{ form.title }}</h4>
</div>
<div class="modal-body">
{% crispy form %}
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<input type="button" class="btn btn-primary" value="Save" id="" onclick="submit_form('{{ form.id }}','{{ form.action }}')">
</div>
</div>
</div>
</form>
However, the form tag is rendered as this:
<form id="edit_action_item" role="form" class="small" name="<input id="id_name" maxlength="256" name="name" type="text" value="Test action item" />">
How can I track down where this gets broken? I kind of suspect that it gets broken because form may be potentially mixing the 'name' field with the form.name attribute.
You have field name in your form. So {{ form.name }} returns output for field name. You can put form name to other variable in __init__:
def __init__(self, *args, **kwargs):
self.helper = FormHelper()
self.helper.form_tag = False
self.helper.layout = Layout()
super(ActionItemForm, self).__init__(*args, **kwargs)
self.form_name = self.name # this line added
and call {{ form.form_name }} in template
<section class="form">
<h5>Contact Form</h5>
<h6>Let Us Know</h6>
<form action="{% url 'web:contact' %}" method="post" class="ajax">
{% csrf_token %}
<p class="left">
<label for="{{form.name.label.id_for_label}}">
{{form.name.label}}
{% if form.name.field.required %}
<small class="star">*</small>
{% endif %}
</label>
{{form.name}}
{% if form.name.errors %}
<span class="error">{{form.name.errors.as_text}}</span>
{% endif %}
</p>
</form>
</section>

Simple Django form in Twitter-Bootstrap modal

I'm trying to run django forms with Twitter-Bootstrap modals. I'd like to know what should I do to return to / after form submission. My views and templates are below.
url.py
urlpatterns = patterns('myapp.views',
url(r'^$', 'main'),
url(r'^add/', 'form_add'),
)
views.py
def main(request):
if request.method == 'POST':
form = MyModelForm(request.POST)
if form.is_valid():
name = form.cleaned_data['name']
request.session['name'] = name
mm = MyModel.objects.create(name=name)
mm.save()
return HttpResponseRedirect('/add') # Redirect after POST
else:
form = MyModelForm()
args = {}
args['last_item'] = MyModel.objects.all().order_by('pk').reverse()[0]
args['form'] = form
return render(request, 'form.html', args)
def form_add(request):
args = {}
name = request.session['name']
return render(request, 'add.html', args)
form.html
{% extends "base.html" %}
{% block content %}
<button type="button" data-toggle="modal"
data-target="#myModal1">Launch modal</button>
<div class="modal" id="myModal1" tabindex="-1" role="dialog"
aria-labelledby="myModal1Label" aria-hidden="true" style="display: none">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h3 id="myModal1Label">Modal header</h3>
</div>
<div class="modal-body">
<form method="POST" id="" action="">
{% csrf_token %}
{{ form.as_p }}
<button>Submit</button>
</form>
</div>
</div>
<p>Last item: {{ last_item }}</p>
{% endblock %}
{% block scripts %}
{% endblock %}
Comment converted to answer.
HttpResponseRedirect('/') instead of '/add'?