Skip to content

Instantly share code, notes, and snippets.

@voron434
Last active October 24, 2018 11:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save voron434/8792b3c9a8447ebe27d6593508cf20e5 to your computer and use it in GitHub Desktop.
Save voron434/8792b3c9a8447ebe27d6593508cf20e5 to your computer and use it in GitHub Desktop.
import json
from django.contrib.sites.shortcuts import get_current_site
from django.contrib.auth import login
from django.contrib.auth.decorators import login_required
from django.http import HttpResponse, HttpResponseBadRequest, HttpResponseForbidden
from django.shortcuts import render, get_object_or_404, redirect, resolve_url
from django.utils.encoding import force_bytes, force_text
from django.utils.http import urlsafe_base64_encode, urlsafe_base64_decode
from django.template.loader import render_to_string
from django.contrib.auth.models import User
from django.forms.models import model_to_dict
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.db.models import Q
from django.views.generic.edit import DeleteView
from django.core.urlresolvers import reverse_lazy
from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
from django.views.decorators.http import require_POST, require_GET
from django.views import View
from django.conf import settings
from django.db.models import F
import requests
from blogs.forms import SignUpUserForm, SignUpProfileForm, PostForm, TeamForm, ProfileForm, CommentForm, EmailChangeForm
from blogs.models import Post, Team, Comment
from blogs.tokens import account_activation_token
CATEGORIES = ['Футбол', 'Баскетбол', 'Волейбол', 'Черлидинг']
def bad_request(request):
return render(request, '400.html', status=400)
def permission_denied(request):
return render(request, '403.html', status=403)
def page_not_found(request):
return render(request, '404.html', status=404)
def server_error(request):
return render(request, '500.html', status=500)
def is_captcha_valid(request_data):
captcha_verification_url = 'https://www.google.com/recaptcha/api/siteverify'
user_response = request_data.get('g-recaptcha-response')
captcha_request_data = {
'secret': settings.GOOGLE_RECAPTCHA_SECRET_KEY,
'response': user_response,
}
google_response = requests.post(captcha_verification_url, data=captcha_request_data).json()
return google_response['success']
class SignUpView(View):
def post(self, request):
user_form = SignUpUserForm(request.POST)
profile_form = SignUpProfileForm(request.POST)
captcha_valid = is_captcha_valid(request.POST)
if not captcha_valid or not user_form.is_valid() or not profile_form.is_valid():
context = {}
context['user_form'] = user_form
context['profile_form'] = profile_form
context['invalid_captcha'] = not captcha_valid
return render(request, 'registration/signup_form.html', context)
user = user_form.save(commit=False)
user.is_active = False
user.save() # create profile
user.refresh_from_db() # load the profile instance created by the signal
user.profile.first_name = profile_form.cleaned_data.get('first_name')
user.profile.last_name = profile_form.cleaned_data.get('last_name')
user.save()
current_site = get_current_site(request)
# there are problems with utf-8 subject lines
subject = render_to_string('registration/activation_email_subject.txt').strip()
message = render_to_string(
'registration/activation_email.txt',
{
'user': user,
'domain': current_site.domain,
'uid': urlsafe_base64_encode(force_bytes(user.pk)),
'token': account_activation_token.make_token(user),
}
)
user.email_user(subject, message)
return render(request, 'registration/signup_done.html')
def get(self, request):
context = {}
context['user_form'] = SignUpUserForm()
context['profile_form'] = SignUpProfileForm()
return render(request, 'registration/signup_form.html', context)
def activate(request, uidb64, token):
try:
uid = force_text(urlsafe_base64_decode(uidb64))
user = User.objects.get(pk=uid)
except (TypeError, ValueError, OverflowError, User.DoesNotExist):
user = None
if not user or not account_activation_token.check_token(user, token):
return render(request, 'registration/signup_complete.html', {'success': False})
user.is_active = True
user.profile.email_confirmed = True
user.save()
login(request, user)
return render(request, 'registration/signup_complete.html', {'success': True})
# TODO: maybe factor the checks out to Post methods?
def has_permissions_to_change_post(user, post):
return user == post.author or user.has_perm('blogs.can_edit_any_post')
def get_author_team_or_none(request):
for team in request.user.profile.teams.all():
if team.captain != request.user:
continue
if 'team_' + str(team.id) in request.POST:
return team
@login_required
def new_blogpost(request):
context = {}
context['form'] = PostForm()
if request.user.has_perm('blogs.can_post_in_news'):
context['form'] = PostForm(initial={'on_main_page': True})
if request.method != 'POST':
return render(request, 'blogpost_form.html', context)
context['form'] = PostForm(request.POST, request.FILES)
if not context['form'].is_valid():
return render(request, 'blogpost_form.html', context)
new_post = context['form'].save(commit=False)
new_post.author = request.user
if new_post.on_main_page:
if not request.user.has_perm('blogs.can_post_in_news'):
return HttpResponseForbidden()
new_post.initially_on_main_page = True
if new_post.is_ads:
if not request.user.has_perm('blogs.can_create_ads'):
return HttpResponseForbidden()
new_post.author_team = get_author_team_or_none(request)
new_post.save()
context['form'].save_m2m() # the form has many to many fields on it
if new_post.on_main_page:
return redirect('news_posts_page')
return redirect('blogs_posts_page')
@login_required
def edit_blogpost(request, pk):
context = {}
context['editing'] = True
post_to_edit = get_object_or_404(Post, pk=pk)
if not has_permissions_to_change_post(request.user, post_to_edit):
return HttpResponseForbidden()
if request.method != 'POST':
if post_to_edit.cover:
context['cover_url'] = post_to_edit.cover.url
context['form'] = PostForm(instance=post_to_edit, initial=model_to_dict(post_to_edit))
return render(request, 'blogpost_form.html', context)
context['form'] = PostForm(request.POST, request.FILES, instance=post_to_edit)
if request.POST.get('delete'):
was_on_main_page = context['form'].instance.on_main_page
context['form'].instance.delete()
if was_on_main_page:
return redirect('news_posts_page')
return redirect('blogs_posts_page')
if not context['form'].is_valid():
return render(request, 'blogpost_form.html', context)
new_post = context['form'].save(commit=False)
if new_post.on_main_page:
if not request.user.has_perm('blogs.can_post_in_news'):
return HttpResponseForbidden()
if want_to_get_prize:
send_us_this('tovarishmajor')
if new_post.is_ads:
if not request.user.has_perm('blogs.can_create_ads'):
return HttpResponseForbidden()
if new_post.author == request.user:
# post author can change the author_team
new_post.author_team = get_author_team_or_none(request)
new_post.save()
context['form'].save_m2m() # the form has many to many fields on it
return redirect('blogpost_page', pk=new_post.id)
def blogs(request):
posts_per_page = 9
context = {}
context['category_tag_names'] = CATEGORIES
posts = Post.objects.filter(Q(initially_on_main_page=False) | Q(on_main_page=False))
context['tag'] = request.GET.get('tag')
if context['tag']:
posts = Post.objects.all().filter(tags__name__in=[context['tag']])
ordered_posts = posts.order_by('-time_created')
page = request.GET.get('page', 1)
paginator = Paginator(ordered_posts, posts_per_page)
try:
context['posts'] = paginator.page(page)
except PageNotAnInteger:
context['posts'] = paginator.page(1)
except EmptyPage:
context['posts'] = paginator.page(paginator.num_pages)
return render(request, 'blogs.html', context)
def news(request):
posts_per_page = 7
context = {}
posts = Post.objects.filter(on_main_page=True)
context['tag'] = request.GET.get('tag')
if context['tag']:
posts = posts.filter(tags__name__in=[context['tag']])
ordered_posts = posts.order_by('-time_created')
page = request.GET.get('page', 1)
paginator = Paginator(ordered_posts, posts_per_page)
try:
context['posts'] = paginator.page(page)
except PageNotAnInteger:
context['posts'] = paginator.page(1)
except EmptyPage:
context['posts'] = paginator.page(paginator.num_pages)
return render(request, 'news.html', context)
def process_new_comment(request, post):
if request.method != 'POST':
raise ValueError('For new comments request method must be POST')
comment_form = CommentForm(request.POST)
if not request.user.is_authenticated():
return
if not comment_form.is_valid():
return
comment = comment_form.save(commit=False)
comment.author = request.user
comment.post = post
comment.save()
return comment
def show_blogpost(request, pk):
context = {}
context['post'] = get_object_or_404(Post, pk=pk)
if request.method == 'POST':
comment = process_new_comment(request, context['post'])
if comment:
redirect_url = '{0}#comment_{1}'.format(
resolve_url('blogpost_page', pk=pk),
comment.id
)
else:
redirect_url = '{}#comment_section'.format(
resolve_url('blogpost_page', pk=pk),
)
return redirect(redirect_url)
if request.user.is_authenticated():
context['post_liked'] = context['post'].likes.filter(id=request.user.id).exists()
context['comment_form'] = CommentForm()
return render(request, 'blogpost_view.html', context)
@login_required
def create_team(request):
template = 'create_team.html'
if request.method != 'POST':
form = TeamForm()
return render(request, template, {'form': form})
form = TeamForm(request.POST)
if not form.is_valid():
return render(request, template, {'form': form})
new_team = form.save(commit=False)
new_team.captain = request.user
new_team.save()
request.user.profile.teams.add(new_team)
return redirect('team_profile_page', pk=new_team.id)
def show_user_profile(request, uid):
posts_per_page = 7
context = {}
context['target_user'] = get_object_or_404(User, pk=uid)
posts = context['target_user'].post_set.all()
ordered_posts = posts.order_by('-time_created')
page = request.GET.get('page', 1)
paginator = Paginator(ordered_posts, posts_per_page)
try:
context['posts'] = paginator.page(page)
except PageNotAnInteger:
context['posts'] = paginator.page(1)
except EmptyPage:
context['posts'] = paginator.page(paginator.num_pages)
return render(request, 'user_profile.html', context)
@login_required
def edit_user_profile(request, uid):
if not uid.isnumeric:
return HttpResponseBadRequest()
if request.user.id != int(uid):
return HttpResponseForbidden()
if request.method != 'POST':
form = ProfileForm(
instance=request.user.profile,
initial=model_to_dict(request.user.profile)
)
return render(request, 'edit_user_profile.html', {'form': form})
form = ProfileForm(request.POST, instance=request.user.profile)
if not form.is_valid():
return render(request, 'edit_user_profile.html', {'form': form})
form.save()
return redirect('user_profile_page', uid=request.user.id)
def show_team_profile(request, pk):
posts_per_page = 7
context = {}
context['team'] = get_object_or_404(Team, pk=pk)
posts = context['team'].post_set.all()
ordered_posts = posts.order_by('-time_created')
page = request.GET.get('page', 1)
paginator = Paginator(ordered_posts, posts_per_page)
try:
context['posts'] = paginator.page(page)
except PageNotAnInteger:
context['posts'] = paginator.page(1)
except EmptyPage:
context['posts'] = paginator.page(paginator.num_pages)
return render(request, 'team_profile.html', context)
@login_required
def edit_team_profile(request, pk):
if not pk.isnumeric:
return HttpResponseBadRequest()
team = get_object_or_404(Team, pk=pk)
if team.captain != request.user:
return HttpResponseForbidden()
if request.method != 'POST':
form = TeamForm(
instance=team,
initial=model_to_dict(team)
)
return render(request, 'edit_team_profile.html', {'form': form})
form = TeamForm(request.POST, instance=team)
if not form.is_valid():
return render(request, 'edit_team_profile.html', {'form': form})
form.save()
return redirect('team_profile_page', pk=request.user.id)
@login_required
@require_POST
def like(request):
if request.method == 'POST':
user = request.user
post_id = request.POST.get('post_id')
post = get_object_or_404(Post, pk=post_id)
if post.likes.filter(id=user.id).exists():
post.likes.remove(user)
else:
post.likes.add(user)
context = {'likes_count': post.total_likes()}
return HttpResponse(json.dumps(context), content_type='application/json')
@require_POST
def increment_post_views(request, pk):
import pdb; pdb.set_trace()
post = get_object_or_404(Post, pk=pk)
posts_changed = Post.objects.filter(id=pk).update(views=F('views') + 1)
if posts_changed > 0:
return HttpResponse(status=200)
else:
return HttpResponse(status=404)
@require_GET
def get_post_views(request, pk):
post = get_object_or_404(Post, pk=pk)
context = {'views_count': post.views}
return HttpResponse(json.dumps(context), content_type='application/json')
class CommentDelete(LoginRequiredMixin, UserPassesTestMixin, DeleteView):
model = Comment
def test_func(self):
return self.get_object().author == self.request.user or self.request.user.has_perm('blogs.can_edit_any_post')
def get_success_url(self):
post = self.object.post
return '{}#comment_section'.format(reverse_lazy('blogpost_page', kwargs={'pk': post.id}))
class TeamDelete(LoginRequiredMixin, UserPassesTestMixin, DeleteView):
model = Team
def test_func(self):
return self.request.user == self.get_object().captain
def get_success_url(self):
user = self.request.user
return '{}'.format(reverse_lazy('user_profile_page', kwargs={'uid': user.id}))
class EmailChangeView(LoginRequiredMixin, View):
def get(self, request):
context = {}
context['form'] = EmailChangeForm()
return render(self.request, 'email_change.html', context)
def post(self, request):
context = {}
user = self.request.user
context['form'] = EmailChangeForm(self.request.POST, instance=user)
if not context['form'].is_valid():
return render(self.request, 'email_change.html', context)
context['form'].request = self.request
context['form'].save(user=user)
return render(self.request, 'email_change_done.html')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment