DRYing out my Django view: Please help me! - django

I hope this is a good first question. I've been trying to DRY out my Django code, but unfortunately I keep getting hit with several errors! (Forgive me if I don't post the code with problems - I'll just post the code that works) I've tried using #decorators, and also putting a view within a view. Please help me!
from django.shortcuts import render_to_response, get_object_or_404, get_list_or_404
from blog.models import Post, User, Blog, Comment
from blog.forms import CommentForm, PostForm, BlogForm
from django.core.urlresolvers import reverse
import datetime
from django.http import HttpResponseRedirect
from django.template import RequestContext
from django import forms
def limiter(request):
if not request.user.is_authenticated():
return HttpResponseRedirect(reverse('accounts.views.login_view'))
def postindex(request):
posts = get_list_or_404(Post.objects.all())
return render_to_response('index.html', {'posts':posts})
def onepost(request, postid):
post = get_object_or_404(Post, pk=postid)
if request.method == 'POST':
if not request.user.is_authenticated():
return HttpResponseRedirect(reverse('accounts.views.login_view'))
form = CommentForm(request.POST)
if form.is_valid():
cd = form.cleaned_data
c = Comment(owner=request.user,
post=Post.objects.get(pk=postid),
time=datetime.datetime.now(),
text=cd['text'])
c.save()
return HttpResponseRedirect(reverse('blog.views.onepost',
args=[postid]))
else:
form = CommentForm()
return render_to_response('single.html',
{'post':post,'comments':post.comment_set.all(),
'form':form},
context_instance=RequestContext(request))
def userlist(request):
users = get_list_or_404(User.objects.all())
return render_to_response('userlist.html', {'users':users})
def bloglist(request, userid):
blogs = get_list_or_404(Blog.objects.filter(owner__pk=userid))
return render_to_response('bloglist.html', {'blogs':blogs})
def postlist(request, blogid):
posts = get_list_or_404(Post.objects.filter(blog__pk=blogid))
return render_to_response('postlist.html', {'posts':posts})
def landing(request):
return render_to_response('landing.html', {})
def dash(request):
if not request.user.is_authenticated():
return HttpResponseRedirect(reverse('accounts.views.login_view'))
user = request.user
blogs = Blog.objects.filter(owner=request.user)
comments = Comment.objects.filter(owner=request.user)
posts = Post.objects.filter(blog__owner=request.user)
return render_to_response('dash.html',
{'user':user, 'blogs':blogs, 'comments':comments, 'posts':posts})
def newpost(request, blogid):
if not request.user.is_authenticated():
return HttpResponseRedirect(reverse('accounts.views.login_view'))
blog = Blog.objects.get(pk=blogid)
if not request.user == blog.owner:
return HttpResponseRedirect(reverse('blog.views.dash'))
if request.method == 'POST':
form = PostForm(request.POST)
if form.is_valid():
cd = form.cleaned_data
p = Post(title=cd['title'],
blog=Blog.objects.get(pk=blogid),
date=datetime.datetime.now(),
content=cd['content'])
p.save()
return HttpResponseRedirect(reverse('blog.views.postlist',
args=[blogid]))
else:
form = PostForm()
return render_to_response('chngpost.html',
{'blog':blog,
'form':form},
context_instance=RequestContext(request))
def editpost(request, postid):
if not request.user.is_authenticated():
return HttpResponseRedirect(reverse('accounts.views.login_view'))
post = Post.objects.get(pk=postid)
if not request.user == post.blog.owner:
return HttpResponseRedirect(reverse('blog.views.dash'))
if request.method == 'POST':
form = PostForm(request.POST)
if form.is_valid():
cd = form.cleaned_data
post.title=cd['title']
post.content=cd['content']
post.save()
return HttpResponseRedirect(reverse('blog.views.onepost',
args=[postid]))
else:
form = PostForm(initial={'title':post.title,'content':post.content})
return render_to_response('chngpost.html',
{'post':post,
'form':form},
context_instance=RequestContext(request))
def delpost(request, postid):
if not request.user.is_authenticated():
return HttpResponseRedirect(reverse('accounts.views.login_view'))
post = Post.objects.get(pk=postid)
if not request.user == post.blog.owner:
return HttpResponseRedirect(reverse('blog.views.dash'))
if request.method == 'POST':
post.delete()
return HttpResponseRedirect(reverse('blog.views.dash'))
return render_to_response('delpost.html',
{'post':post},
context_instance=RequestContext(request))
def newblog(request):
if not request.user.is_authenticated():
return HttpResponseRedirect(reverse('accounts.views.login_view'))
if request.method == 'POST':
form = BlogForm(request.POST)
if form.is_valid():
cd = form.cleaned_data
b = Blog(title=cd['title'],
owner=request.user)
b.save()
return HttpResponseRedirect(reverse('blog.views.bloglist',
args=[request.user.pk]))
else:
form = BlogForm()
return render_to_response('chngpost.html',
{'form':form},
context_instance=RequestContext(request))
def delcomment(request, commentid):
if not request.user.is_authenticated():
return HttpResponseRedirect(reverse('accounts.views.login_view'))
comment = Comment.objects.get(pk=commentid)
if not (request.user == comment.post.blog.owner) | (request.user == comment.owner):
return HttpResponseRedirect(reverse('blog.views.dash'))
if request.method == 'POST':
comment.delete()
return HttpResponseRedirect(reverse('blog.views.dash'))
return render_to_response('delpost.html',
{},
context_instance=RequestContext(request))
(Hope that's formatted properly) The code I'd like to factor out especially is
if not request.user.is_authenticated():
return HttpResponseRedirect(reverse('accounts.views.login_view'))
But of course any more suggestions would be appreciated! Thank you so much!
`

Use login_required decorator (docs)
Use modelforms for editing/creating models. (docs)
If you need to just pass something to template, use direct_to_template generic view (docs)

You can use #login_required decorator for that. You can find out more at Django documentation: http://docs.djangoproject.com/en/dev/topics/auth/#django.contrib.auth.decorators.login_required.
Please describe any problems that you are experiencing.

Related

The view blogapp.views.blogpost didn't return an HttpResponse object. It returned None instead

from django import forms
from .models import Blog
I just rewrite code this point,
from ↓:
# class BlogPost(forms.ModelForm):
# class Meta:
# model = Blog
# fields = ['title', 'body']
to ↓:
class BlogPost(forms.Form):
email = forms.EmailField()
files = forms.FileField()
url = forms.URLField()
words = forms.CharField(max_length=200)
max_number = forms.ChoiceField(choices=[('1','one'), ('2','two'),('3','three')])
and views.py file is here ↓:
from django.shortcuts import render, get_object_or_404, redirect
from .models import Blog
from django.utils import timezone
from .form import BlogPost
from django.views.decorators.http import require_http_methods
# Create your views here.
def home(request):
blogs = Blog.objects #쿼리셋
return render(request, 'home.html', {'blogs'`enter code here`:blogs})
def detail(request, blog_id):
details = get_object_or_404(Blog, pk=blog_id)
return render(request, 'detail.html', {'details':details})
def new(request):
return render(request, 'new.html')
def create(request):
blog = Blog()
blog.title = request.GET['title']
blog.body = request.GET['body']
blog.pub_date = timezone.datetime.now()
blog.save()
return redirect('/blog/'+str(blog.id)) #이 URL로 넘기세요 처리된 정보를
def blogpost(request):
if request.method =='POST':
form = BlogPost(request.POST)
if form.is_valid():
post = form.save(commit=False)
# post.pub_date = timezone.now()
post.save()
return redirect('home')
else:
form = BlogPost()
return render(request, 'newblog.html',{'form':form})
I don't know why I only rewrite 'form.py' file, but vscode program says "The view blogapp.views.blogpost didn't return an HttpResponse object. It returned None instead."
what should I do?? help..
def blogpost(request):
if request.method =='POST':
form = BlogPost(request.POST)
if form.is_valid():
post = form.save(commit=False)
# post.pub_date = timezone.now()
post.save()
return redirect('home')
else:
form = BlogPost()
return render(request, 'newblog.html',{'form':form})
You don't have a return statement on here due to your if statement and indentation.
Write it like:
def blogpost(request):
if request.method =='POST':
form = BlogPost(request.POST)
if form.is_valid():
post = form.save(commit=False)
# post.pub_date = timezone.now()
post.save()
return redirect('home')
else:
form = BlogPost()
return render(request, 'newblog.html',{'form':form})
And it should work.

Django: didn't return a HttpResponse object error

I am trying to make a Post form, but HttPResponse occurs.In my code, there is a redirect method, and I think it is considered as a httpresponse, isn't it?
I am just a begineer, so if someone could find an easy mistake, I would appreciate
from django.shortcuts import render,redirect
from .forms import DayCreateForm
def index(request):
return render(request,'diary/day_list.html')
def add(request):
form = DayCreateForm(request.POST or None)
if request.method == 'POST'and form.is_valid():
form.save()
return redirect('diary:index')
context ={
'form':form
}
return render(request,'diary/day_form.html',context)
In your code there is no HttpResponse returned if request.method is not POST, so try to add a return of HttpResponse in the case of 'not Post'.
You are not returning any HTTP response if the requested method other than HTTP POST. So, try the below snippet
from django.http.response import HttpResponse
def add(request):
if request.method == 'POST':
form = DayCreateForm(request.POST or None)
if form.is_valid():
form.save()
return redirect('diary:index')
else:
return HttpResponse("form is not valid")
else:
form = DayCreateForm()
context = {
'form': form
}
return render(request, 'diary/day_form.html', context)

Django - passing a parameter from page redirect

I just started with Python and Django and want to redirect a user to a home page after successful form-registration with a head-massage changed to "You have successfully registered".
My code without changing a massage after redirection is:
urls.py:
urlpatterns = [
path('', IndexView.as_view(), name = 'index'),
path('register/', views.register, name = 'register'),
]
views.py:
class IndexView(TemplateView):
template_name = 'first_ap/index.html'
def get_context_data(self, *args, **kwargs):
t_user = 'Hello my friend'
context = {
'viva':t_user
}
return context
def register(request):
if request.method == "POST":
form = RegForm(request.POST)
if form.is_valid():
new_user = form.save(commit=False)
new_user.set_password(form.cleaned_data['password'])
new_user.save()
return redirect('index')
else:
form = RegForm()
return render(request, 'first_ap/register.html', {'form': form})
In html file I put:
<h1>{{ viva }}!</h1>
How should I modify a code to change a context after redirection from "Hello my friend" to "You have successfully registered"? I tried several options but they all failed.
Why dont you just save the message in an object variable:
class IndexView(TemplateView):
template_name = 'first_ap/index.html'
text='Hello my friend'
def get_context_data(self, *args, **kwargs):
context = {
'viva':self.text
}
return context
def register(request):
if request.method == "POST":
form = RegForm(request.POST)
if form.is_valid():
IndexView.text='You have registered'
new_user = form.save(commit=False)
new_user.set_password(form.cleaned_data['password'])
new_user.save()
return redirect('index')
else:
form = RegForm()
return render(request, 'first_ap/register.html', {'form': form})
Solution:
from django.urls import reverse
class IndexView(TemplateView):
template_name = 'first_ap/index.html'
def get_context_data(self, *args, **kwargs):
# request.GET contains the query parameters, check if `first_visit` is 1 or not
is_first_visit = self.request.GET.get('first_visit', 0) == "1"
if is_first_visit is False:
t_user = 'Hello my friend'
else:
t_user = 'You have successfully registered'
context = {
'viva': t_user
}
return context
def register(request):
if request.method == "POST":
form = RegForm(request.POST)
if form.is_valid():
new_user = form.save(commit=False)
new_user.set_password(form.cleaned_data['password'])
new_user.save()
# add a query parameter to indicate user's first visit
return redirect(reverse('index') + "?first_visit=1")
else:
form = RegForm()
return render(request, 'first_ap/register.html', {'form': form})
Add a query parameter first_visit as 1 (random value) in the redirect call after successful registration.
Access the query parameter using self.request.GET dict
Change the context value based on the value of first_visit

Django link two apps

im currently facing the problem that i want to call a view from another app (accounts app which holds the user model) within my main app (a blog app).
this is the error i get:
django.core.exceptions.FieldError: Unknown field(s) (username) specified for User
urls.py
...
from quickblog import views as core_views
from accounts import views as views_accounts
...
url(r'^myaccount/$', views_accounts.view_profile, name='myaccount'),
views.py (accounts app):
from django.shortcuts import render, redirect
from django.urls import reverse
from accounts.forms import (
RegistrationForm,
EditProfileForm
)
from django.contrib.auth.models import User
from django.contrib.auth.forms import PasswordChangeForm
from django.contrib.auth import update_session_auth_hash
def register(request):
if request.method == 'POST':
form = RegistrationForm(request.POST)
if form.is_valid():
form.save()
return redirect(reverse('accounts:home'))
else:
form = RegistrationForm()
args = {'form': form}
return render(request, 'reg_form.html', args)
def view_profile(request, pk=None):
if pk:
user = User.objects.get(pk=pk)
else:
user = request.user
args = {'user': user}
return render(request, 'profile.html', args)
def edit_profile(request):
if request.method == 'POST':
form = EditProfileForm(request.POST, instance=request.user)
if form.is_valid():
form.save()
return redirect(reverse('accounts:view_profile'))
else:
form = EditProfileForm(instance=request.user)
args = {'form': form}
return render(request, 'edit_profile.html', args)
def change_password(request):
if request.method == 'POST':
form = PasswordChangeForm(data=request.POST, user=request.user)
if form.is_valid():
form.save()
update_session_auth_hash(request, form.user)
return redirect(reverse('accounts:view_profile'))
else:
return redirect(reverse('accounts:change_password'))
else:
form = PasswordChangeForm(user=request.user)
args = {'form': form}
return render(request, 'change_password.html', args)
This is my first django app, is there maybe anything i need to know about linking two apps within one project?
thanks

Is it possible for superuser to create more than one post, and user to be post only one post?

currently, user can create only one post. but as a superuser I want to create more than one. I tried to do it in admin page but it won't work. Is there a way to do this?
#login_required
def add_category(request):
if Category.objects.filter(author=request.user).exists():
return render(request,'main/category_already_exists.html')
if request.method == 'POST':
category = Category(author=request.user)
form = CategoryForm(request.POST, instance=category)
if form.is_valid():
form.save(commit=True)
return redirect('index')
else:
form = CategoryForm()
return render(request, 'main/add_category.html', {'form':form})
#login_required
def add_category(request):
if not request.user.is_superuser and Category.objects.filter(author=request.user).exists():
return render(request,'main/category_already_exists.html')
if request.method == 'POST':
category = Category(author=request.user)
form = CategoryForm(request.POST, instance=category)
if form.is_valid():
form.save(commit=True)
return redirect('index')
else:
form = CategoryForm()
return render(request, 'main/add_category.html', {'form':form})