Django 2.1.2 - AttributeError: 'UserProfile' object has no attribute 'object' - django

I am having problems with a class named SearchView(ListView) which I am using to display a search query. This class "SearchView" is being inherited from a UserProfile View, so that users can use the search bar in the profile view to search any post. When I try to load the route /users/// it raise the Following error: 'UserProfile' object has no attribute 'object. I guess it is because I am overriding the get_context_data() method.
This is the code of the SearchView class:
class SearchView(ListView):
model = Post
def get_context_data(self, *args, **kwargs):
context = super().get_context_data(**kwargs)
try:
context['list_result'] = self.result
except:
messages.error(self.request, 'test')
finally:
return context
def get(self, request, *args, **kwargs):
if request.GET.get('search'):
search_query = request.GET.get('search', None)
self.result = Post.objects.filter(title__icontains=search_query).order_by()
if not self.result:
messages.error(request, f'No results found for {search_query}')
return super().get(request, *args, **kwargs)
This is the code of the UserProfile View:
#method_decorator(login_required, name='dispatch')
class UserProfile(SearchView, DetailView):
model = User
context_object_name = 'user_object'
def get_context_data(self, **kwargs):
data = super().get_context_data(**kwargs)
try:
relevant_post = Post.objects.filter(author_id=self.kwargs.get('pk')).order_by('-rating')[0]
data['relevant_post'] = relevant_post
except IndexError:
pass
finally:
return data
This is the search template:
{% extends 'blog/base.html' %}
{% load static %}
{% block content %}
<form class="align-middle w-50" type="GET" style="margin: 0">
<span class="fa fa-search form-control-feedback"></span>
<input type="text" class="form-control" name="search"
placeholder="Search ..">
</form>
{% if list_result %}
<h2>Results: </h2>
{% for result in list_result %}
<div class="container">
<article class="media content-section">
<div class="media-body">
<div class="article-metadata">
<img class="rounded-circle article-img" src="{{ result.author.profile.image.url }} "/>
<a class="mr-2" href="{% url 'profile' result.author.id result.author.username %}">{{ result.author }}</a>
<small class="text-muted">{{ result.post_date|date:"N d, o" }} . </small>
<div class="float-right mt-1">
<img src="{% static 'blog/rating_icon.svg' %}" alt="Ratings">
<div></div>
<medium class="ml-2">{{ result.rating }}</medium>
</div>
<h2><a class="article-title" href="{% url 'post-detail' result.id result.title %}">{{ result.title }}</a></h2>
<a href="{% url 'post-detail' result.id result.title%}">
Click here for more details.
</a>
</div>
</div>
</article>
</div>
{%endfor%}
{%endif%}
{%endblock%}
Thank you in advance.

try adding self.object = self.get_object() to get_context_data. Because a DetailView needs an object attribute

Related

How to by default not show list of items?

There is a page where the list of elements is displayed. Also on this page there is a search by value. When I enter a value, the page only displays elements with that value.
I need to make the page show nothing but the search by default. And only after the query, the page shows the elements with the entered value. How to do it?
home.html
<div class="headtext">
<form method="GET" action="{% url 'search' %}">
<input type="search" type="text" name="q" prequired placeholder="Put appnumber">
<button type="submit">Find</button>
</form>
</div>
<div>
{% for application in object_list %}
<div>
<p>Application: {{ application.appnumber }}, status: {{ application.status }}</p>
</div>
{% endfor %}
</div>
urls.py
from django.urls import path
from .views import HomeView, Search
urlpatterns = [
path('', HomeView.as_view(), name="home"),
path('search/', Search.as_view(), name="search"),
views.py
class HomeView(ListView):
model = Application
template_name = 'home.html'
class Search(ListView):
template_name = 'home.html'
def get_queryset(self):
return Application.objects.filter(appnumber__icontains=self.request.GET.get("q"))
def get_context_data(self, *args, **kwargs):
context = super().get_context_data(*args, **kwargs)
context["q"] = self.request.GET.get("q")
return context
Simply check the existence of the object_list context variable:
<div class="headtext">
<form method="GET" action="{% url 'search' %}">
<input type="search" type="text" name="q" prequired placeholder="Put appnumber">
<button type="submit">Find</button>
</form>
</div>
{% if object_list %}
<div>
{% for application in object_list %}
<div>
<p>Application: {{ application.appnumber }}, status: {{ application.status }}</p>
</div>
{% endfor %}
</div>
{% endif %}
Edit: I hadn't noticed that HomeView is also a subclass of ListView. Change it to:
class HomeView(TemplateView):
template_name = 'home.html'
You can have an method that will take 'q' from request and return it or None.
Then your get_queryset can use this parameter to return object list you need.
Something like this should work
class Search(ListView):
template_name = 'home.html'
def get_q(self):
q = self.request.GET.get('q', None)
return q
def get_queryset(self):
q = self.get_q()
if not q:
return []
return Application.objects.filter(appnumber__icontains=q)

Django- Template not found

I can't seem to get my delete, edit and add review functionality working. The errors come as soon as I try to navigate to the urls I have set up. When I try and add a new review using my link on the reviews page I get the below message:
TemplateDoesNotExist at /reviews/add
I don't understand why because I have linked the url above to the template, which I have created.
The issue I have with my edit/delete views is that the url it searches for when I click the button is just /edit/ or /delete/ rather than reviews/edit/int:pk or reviews/delete/int:pk as per my urls.
I have pasted my code below, any help would be much appreciated! I have the feeling I am going to kick myself when I realise!
reviews.html:
{% extends "base.html" %}
{% load static %}
{% block content %}
<div class="container-fluid home-container">
<div class="row align-items-center">
<div class="col-sm-12 text-center mt-4">
<h2><strong>Reviews</strong></h2>
</div>
</div>
{% for review in reviews %}
<hr class="hr-1">
<div class="row featurette">
<div class="col-sm-12">
<h2 class="featurette-heading">{{ review.title }}</h2>
<p class="lead">{{ review.content }}</p>
<div class="row justify-content-between mx-1">
<p>By: {{ review.user }}</p>
<p>Created on: {{ review.created }}</p>
<p>Last Updated: {{ review.updated }}</p>
</div>
<!-- Add user authentication if -->
<div class="text-center">
<a href="edit/{{ review.id }}" class="mx-2">
<button class="positive-button mb-2">Edit</button></a>
<a href="delete/{{ review.id }}" class="mx-2 mb-2">
<button class="negative-button">Delete</button></a>
</div>
</div>
</div>
{% endfor %}
<div class="row">
<div class="col-sm-12 text-center py-4">
{% if user.is_authenticated %}
<a href="{% url 'home:add_review' %}">
<button class="positive-button-lg">Add a review</button>
</a>
{% else %}
<p>If you would like to add your own review, please login or sign up if you haven't already!</p>
{% endif %}
</div>
</div>
</div>
{% endblock %}
add_review.html:
{% extends "base.html" %}
{% load static %}
{% block content %}
<div class="container-fluid">
<div class="row justify-content-center">
<div class="col-auto text-center p-3">
<form method="post" style="margin-top: 1.3em;">
{{ review_form }}
{% csrf_token %}
<button type="submit" class="btn btn-primary btn-lg">Submit</button>
</form>
</div>
</div>
{% endblock %}
views.py:
from django.shortcuts import render
from django.views import View
from django.urls import reverse_lazy
from django.views.generic import UpdateView, DeleteView
from .models import Reviews
from .forms import ReviewForm
def home(request):
''' Returns the home page.'''
return render(request, 'home/index.html')
def reviews(request):
''' Returns the reviews page.'''
serialized_reviews = []
reviews = Reviews.objects.all()
for review in reviews:
serialized_reviews.append({
"title": review.title,
"content": review.content,
"user": review.user,
"created": review.created,
"updated": review.updated,
})
context = {
"reviews": serialized_reviews
}
print(serialized_reviews)
return render(request, 'home/reviews.html', context)
class AddReview(View):
'''View which allows the user to add a new review.'''
def get(self, request, *args, **kwargs):
review = Reviews
review_form = ReviewForm
context = {
'review': review,
'review_form': review_form,
'user': review.user,
'title': review.title,
'content': review.content,
}
return render(request, 'add_review.html', context)
def post(self, request, *args, **kwargs):
review_form = ReviewForm(data=request.POST)
if review_form.is_valid():
obj = review_form.save(commit=False)
obj.user = request.user
obj.save()
return redirect("home:reviews")
class DeleteReview(DeleteView):
'''View which allows the user to delete the selected review.'''
model = Reviews
template_name = 'delete_review.html'
success_url = reverse_lazy('reviews')
class EditReview(UpdateView):
'''View which allows the user to edit the selected review.'''
model = Reviews
template_name = 'edit_review.html'
fields = ['title', 'content']
urls.py:
from django.urls import path
from . import views
app_name = 'home'
urlpatterns = [
path('', views.home, name='home'),
path('reviews', views.reviews, name='reviews'),
path('reviews/add', views.AddReview.as_view(), name='add_review'),
path('reviews/delete/<int:pk>', views.DeleteReview.as_view(), name='delete_review'),
path('reviews/edit/<int:pk>', views.EditReview.as_view(), name='edit_review'),
]
The main difference is my app name, which is 'core'. Also, I forgot to add the content field to the model, but that is easily done, the form will just handle it as soon as you do the migration. (except on list.html)
models.py
from django.db import models
from django.contrib.auth import get_user_model
from django.utils import timezone
class Reviews(models.Model):
user = models.ForeignKey(get_user_model(), on_delete=models.CASCADE)
title = models.CharField(max_length=128)
created_at = models.DateTimeField(auto_now_add=timezone.now())
updated_at = models.DateTimeField(auto_now=timezone.now())
forms.py
from django import forms
from core.models import Reviews
class ReviewsForm(forms.ModelForm):
class Meta:
model = Reviews
fields = '__all__'
views.py
from core.models import Reviews
from core.forms import ReviewsForm
from django.shortcuts import render, redirect
def list_reviews(request):
reviews = Reviews.objects.all()
context = {
"reviews": reviews
}
return render(request, 'reviews/list.html', context)
def add_review(request):
if request.method == 'POST':
form = ReviewsForm(request.POST)
if form.is_valid():
form.save()
return redirect('/reviews/')
else:
form = ReviewsForm()
context = {
'form': form
}
return render(request, 'reviews/detail.html', context)
def edit_review(request, pk):
if request.method == 'POST':
form = ReviewsForm(request.POST)
if form.is_valid():
obj = Reviews.objects.get(id=pk)
obj.title = form.cleaned_data['title']
obj.user = form.cleaned_data['user']
obj.save()
return redirect('/reviews/')
else:
obj = Reviews.objects.get(id=pk)
form = ReviewsForm(instance=obj)
context = {
'form': form
}
return render(request, 'reviews/detail.html', context)
def delete_review(request, pk):
obj = Reviews.objects.get(id=pk)
obj.delete()
return redirect('/reviews/')
urls.py
from django.urls import path
import core.views as views
app_name = 'core'
urlpatterns = [
path('reviews/', views.list_reviews, name='list-reviews'),
path('reviews/add', views.add_review, name='add-review'),
path('reviews/edit/<int:pk>/', views.edit_review, name='edit-review'),
path('reviews/delete/<int:pk>/', views.delete_review, name='delete-review'),
]
list.html
{% extends "base.html" %}
{% load static %}
{% block content %}
<div class="container-fluid home-container">
<div class="row align-items-center">
<div class="col-sm-12 text-center mt-4">
<h2><strong>Reviews</strong></h2>
</div>
</div>
{% for review in reviews %}
<hr class="hr-1">
<div class="row featurette">
<div class="col-sm-12">
<h2 class="featurette-heading">{{ review.title }}</h2>
<p class="lead">{{ review.content }}</p>
<div class="row justify-content-between mx-1">
<p>By: {{ review.user }}</p>
<p>Created on: {{ review.created_at }}</p>
<p>Last Updated: {{ review.updated_at }}</p>
</div>
<!-- Add user authentication if -->
<div class="text-center">
<a href="{% url 'core:edit-review' pk=review.id %}" class="mx-2">
<button class="positive-button mb-2">Edit</button></a>
<a href="{% url 'core:delete-review' pk=review.id %}" class="mx-2 mb-2">
<button class="negative-button">Delete</button></a>
</div>
</div>
</div>
{% endfor %}
<div class="row">
<div class="col-sm-12 text-center py-4">
{% if user.is_authenticated %}
<a href="{% url 'core:add-review' %}">
<button class="positive-button-lg">Add a review</button>
</a>
{% else %}
<p>If you would like to add your own review, please login or sign up if you haven't already!</p>
{% endif %}
</div>
</div>
</div>
{% endblock %}
detail.html
{% extends "base.html" %}
{% load static %}
{% block content %}
<div class="container-fluid">
<div class="row justify-content-center">
<div class="col-auto text-center p-3">
<form method="post" style="margin-top: 1.3em;">
{% csrf_token %}
<table>
{{ form }}
</table>
<button type="submit" class="btn btn-primary btn-lg">Save</button>
</form>
</div>
</div>
{% endblock %}
According to your urls, It is a review/edit/<int:pk>.
So you must add same thing in href tag.
Change this:
<a href="edit/{{ review.id }}"
To this:
<a href="review/edit/{{ review.id }}"
That's why you are getting that error
I've fixed it, firstly the path in my add_review view was wrong, which I have amended and it now works (thanks Ivan).
I also was not actually bringing the ID through on my 'reviews' view in the first place, so when following the links on my edit and review buttons, it didn't know what I meant by 'id', as I hadn't specified what that was in the view context.
Thanks for the help all!
I think you're writing in your urls the wrong way, like this below your div text-center:
<a href="edit/{{ review.id }}" class="mx-2">
It should be:
<a href="{% url 'yourappname:edit' review.id %}">

Converting Django DeleteView to work with ajax

Im new to django and im stuck with an issue with ajax. I have the code below.
I have a django delte view. I want to use this with ajax. Right now the view is working but the CSRF Token doesnt render.
I want to try and use a class based view as im new to learn. Im not sure why the CSRF TOKEN is not being rendered in the AJAX version. It appears when a browser is used but not when ajax is used.
Can someone please help ?
view.py
class DeleteOrderItemView(SuccessMessageMixin, generic.DeleteView):
model = OrderItem
template_name = 'pos/order_item_confirm_delte.html'
# overwritten the delete to have a conformation code. Pending items do not need a conformation code.
def delete(self, *args, **kwargs):
print("I was called !")
self.object = self.get_object()
conformation_code = self.request.POST.get('cancellation_code')
if conformation_code == str(12345) or self.object.status == "Pending":
# Record code and logged in user
messages.success(self.request, "Order item {} deleted.".format(self.object.item.name))
# print cancelled KOT
return super(DeleteOrderItemView, self).delete(*args, **kwargs)
else:
messages.warning(self.request, "Incorrect conformation code.")
return HttpResponseRedirect(reverse('pos:delete_order_item', kwargs={'pk': self.object.pk}))
def get_success_url(self, **kwargs):
self.object = self.get_object()
order_pk = self.object.order.pk
return reverse_lazy('pos:order_details', kwargs={'pk': order_pk})
def render_to_response(self, context, **response_kwargs):
""" Allow AJAX requests to be handled more gracefully """
if self.request.is_ajax():
context = self.get_context_data(**response_kwargs)
rendered = render_to_string(self.template_name, context)
return JsonResponse({'delete_form': rendered}, safe=False, **response_kwargs)
else:
return super(generic.DeleteView, self).render_to_response(context, **response_kwargs)
Javascript
/* Load the delete form */
$("#js_order_list_items").on("click", "#js_remove_item", function(){
$("#modal-actions").modal("show");
remove_url = $('#js_remove_item').attr('js_delete_url')
$.ajax({
url: remove_url,
type: 'get',
dataType: 'json',
beforeSend: function () {
$("#modal-actions").modal("show");
},
success: function (data) {
console.log(data.delete_form)
$("#modal-actions .modal-content").html(data.delete_form)
}
})
});
HTML
{% load static %}
{% block content %}
<div class="container">
<br/>
<div class="col-12 alert alert-danger">
<h4>Delete item for {{ orderitem.order.customer.name }}</h4>
</div>
<div class="row">
<div class="col-6">
<ul class="list-group">
<li class="list-group-item"><strong>{{ orderitem.item.name }}</strong></li>
<li class="list-group-item">Quantity: {{ orderitem.quantity }}</li>
<li class="list-group-item">Price: {{ orderitem.price }}</li>
<li class="list-group-item">Ordered by: {{ orderitem.order.user.username }}</li>
<li class="list-group-item">
{% if messages %}
<div class="alert alert-danger" role="alert">
{% for message in messages %}
{{ message }}
{% endfor %}
</div>
{% endif %}
</li>
</ul>
</div>
</div>
<div class="row">
<div class="col-12">
<hr/>
<form method="POST" action="{% url 'pos:delete_order_item' pk=orderitem.pk %}" class="js_confirm_delete_form">
{% csrf_token %}
{% if orderitem.status == 'Confirmed' %}
<label>Cancellation Code: </label> <input type="password" id="cancellation_code" name="cancellation_code"><br/><hr/>
{% endif %}
<input type="submit" value="Confirm" class="btn btn-danger btn-large btn-lg">
<button class="btn btn-secondary btn-large btn-lg" type="button">Cancel</button>
</form>
</div>
</div>
</div>
{% endblock %}
I found the issue my self. The render_to_string needs the request passed to it for the csrf_token to work.
rendered = render_to_string(self.template_name, context, request=self.request)

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.

Django - 405 POST not allowed

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