GNNRecom/rank/views.py

144 lines
4.8 KiB
Python
Raw Permalink Normal View History

2021-11-16 07:04:52 +00:00
import re
from django.conf import settings
from django.contrib.auth import authenticate, login, logout, REDIRECT_FIELD_NAME
from django.contrib.auth.decorators import login_required
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.auth.models import User
from django.shortcuts import render, redirect
from django.views import View
from django.views.generic import ListView, DetailView
from django.views.generic.detail import SingleObjectMixin
from gnnrec.kgrec import recall, rank
from .models import Author, Paper
class LoginView(View):
def get(self, request):
if request.user.is_authenticated:
return redirect('rank:index')
return render(request, 'rank/login.html', {'login_url': request.get_full_path()})
def post(self, request):
username = request.POST.get('username')
password = request.POST.get('password')
user = authenticate(request, username=username, password=password)
if user is not None:
login(request, user)
return redirect(self.get_redirect_url())
else:
return render(request, 'rank/login.html', {'message': '用户名或密码错误'})
def get_redirect_url(self):
return self.request.POST.get(REDIRECT_FIELD_NAME) \
or self.request.GET.get(REDIRECT_FIELD_NAME, 'rank:index')
def logout_view(request):
logout(request)
return redirect('rank:login')
class RegisterView(View):
def get(self, request):
return render(request, 'rank/register.html')
def post(self, request):
username = request.POST.get('username')
password = request.POST.get('password')
password2 = request.POST.get('password2')
name = request.POST.get('name')
email = request.POST.get('email')
message = ''
if not re.fullmatch('[0-9A-Za-z_]+', username):
message = '用户名只能包含字母、数字和下划线'
elif User.objects.filter(username=username).exists():
message = '用户名已存在'
elif password != password2:
message = '两次密码不一致'
if message:
return render(request, 'rank/register.html', {'message': message})
User.objects.create_user(username, email, password, first_name=name)
return redirect('rank:login')
@login_required
def index(request):
return render(request, 'rank/index.html')
# 召回和学者排名模块上下文对象在RankConfig.ready()中初始化
recall_ctx = None
rank_ctx = None
class SearchPaperView(LoginRequiredMixin, ListView):
template_name = 'rank/search_paper.html'
def get_queryset(self):
if not self.request.GET.get('q'):
return Paper.objects.none()
_, pid = recall.recall(recall_ctx, self.request.GET['q'], settings.PAGE_SIZE)
return sorted(Paper.objects.filter(id__in=pid), key=lambda p: pid.index(p.id))
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['q'] = self.request.GET.get('q', '')
return context
class PaperDetailView(LoginRequiredMixin, DetailView):
model = Paper
# 参考 https://docs.djangoproject.com/en/3.2/topics/class-based-views/mixins/#using-singleobjectmixin-with-listview
class AuthorDetailView(LoginRequiredMixin, SingleObjectMixin, ListView):
template_name = 'rank/author_detail.html'
paginate_by = settings.PAGE_SIZE
def get(self, request, *args, **kwargs):
self.object = self.get_object(queryset=Author.objects.all())
return super().get(request, *args, **kwargs)
def get_queryset(self):
return self.object.papers.order_by('-n_citation')
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['author'] = self.object
return context
class SearchAuthorView(LoginRequiredMixin, ListView):
template_name = 'rank/search_author.html'
def get_queryset(self):
if not self.request.GET.get('q'):
return Author.objects.none()
return Author.objects.filter(name=self.request.GET['q'])
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['q'] = self.request.GET.get('q', '')
return context
class AuthorRankView(LoginRequiredMixin, ListView):
template_name = 'rank/author_rank.html'
def get_queryset(self):
if not self.request.GET.get('q'):
return Author.objects.none()
_, aid = rank.rank(rank_ctx, self.request.GET['q'])
return sorted(Author.objects.filter(id__in=aid), key=lambda a: aid.index(a.id))
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['q'] = self.request.GET.get('q', '')
return context