Merge branch 'virusdefender-dev'

This commit is contained in:
virusdefender
2015-11-10 23:05:28 +08:00
8 changed files with 213 additions and 130 deletions

View File

@@ -0,0 +1,24 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('account', '0013_userprofile'),
]
operations = [
migrations.AddField(
model_name='userprofile',
name='phone_number',
field=models.CharField(max_length=15, null=True, blank=True),
),
migrations.AddField(
model_name='userprofile',
name='school',
field=models.CharField(max_length=200, null=True, blank=True),
),
]

View File

@@ -68,6 +68,9 @@ class UserProfile(models.Model):
submissions_number = models.IntegerField(default=0) submissions_number = models.IntegerField(default=0)
# JSON字典用来表示该用户的问题的解决状态 1为ac2为正在进行 # JSON字典用来表示该用户的问题的解决状态 1为ac2为正在进行
problems_status = JSONField(default={}) problems_status = JSONField(default={})
phone_number = models.CharField(max_length=15, blank=True, null=True)
school = models.CharField(max_length=200, blank=True, null=True)
class Meta: class Meta:
db_table = "user_profile" db_table = "user_profile"

View File

@@ -1,7 +1,7 @@
# coding=utf-8 # coding=utf-8
from rest_framework import serializers from rest_framework import serializers
from .models import User from .models import User, UserProfile
class UserLoginSerializer(serializers.Serializer): class UserLoginSerializer(serializers.Serializer):
@@ -65,10 +65,20 @@ class SSOSerializer(serializers.Serializer):
class EditUserProfileSerializer(serializers.Serializer): class EditUserProfileSerializer(serializers.Serializer):
avatar = serializers.CharField(max_length=50, required=False, default=None) avatar = serializers.CharField(max_length=50, required=False, default=None)
phone = serializers.CharField(min_length=11, max_length=11, required=False, allow_blank=True, default=None) blog = serializers.URLField(required=False, allow_blank=True, default='')
blog = serializers.URLField(required=False, allow_blank=True, default=None) mood = serializers.CharField(max_length=60, required=False, default='')
mood = serializers.CharField(max_length=60, required=False, allow_blank=True, default=None) hduoj_username = serializers.CharField(max_length=30, required=False, allow_blank=True, default='')
hduoj_username = serializers.CharField(max_length=30, required=False, allow_blank=True, default=None) bestcoder_username = serializers.CharField(max_length=30, required=False, allow_blank=True, default='')
bestcoder_username = serializers.CharField(max_length=30, required=False, allow_blank=True, default=None) codeforces_username = serializers.CharField(max_length=30, required=False, allow_blank=True, default='')
codeforces_username = serializers.CharField(max_length=30, required=False, allow_blank=True, default=None) school = serializers.CharField(max_length=200, required=False, allow_blank=True, default='')
phone_number = serializers.CharField(max_length=15, required=False, allow_blank=True, default='')
class UserProfileSerializer(serializers.ModelSerializer):
class Meta:
model = UserProfile
fields = ["avatar", "blog", "mood", "hduoj_username", "bestcoder_username", "codeforces_username",
"rank", "accepted_number", "submissions_number", "problems_status", "phone_number", "school"]

View File

@@ -18,11 +18,13 @@ from mail.tasks import send_email
from .decorators import login_required from .decorators import login_required
from .models import User, UserProfile from .models import User, UserProfile
from .serializers import (UserLoginSerializer, UserRegisterSerializer, from .serializers import (UserLoginSerializer, UserRegisterSerializer,
UserChangePasswordSerializer, UserChangePasswordSerializer,
UserSerializer, EditUserSerializer, UserSerializer, EditUserSerializer,
ApplyResetPasswordSerializer, ResetPasswordSerializer, ApplyResetPasswordSerializer, ResetPasswordSerializer,
SSOSerializer, EditUserProfileSerializer) SSOSerializer, EditUserProfileSerializer, UserProfileSerializer)
from .decorators import super_admin_required from .decorators import super_admin_required
@@ -226,6 +228,37 @@ class UserInfoAPIView(APIView):
return success_response(UserSerializer(request.user).data) return success_response(UserSerializer(request.user).data)
class UserProfileAPIView(APIView):
@login_required
def get(self, request):
"""
返回这个用户的个人信息
---
response_serializer: UserSerializer
"""
return success_response(UserSerializer(request.user).data)
@login_required
def put(self, request):
serializer = EditUserProfileSerializer(data=request.data)
if serializer.is_valid():
data = serializer.data
user_profile = request.user.userprofile
if data["avatar"]:
user_profile.avatar = data["avatar"]
user_profile.mood = data["mood"]
user_profile.hduoj_username = data["hduoj_username"]
user_profile.bestcoder_username = data["bestcoder_username"]
user_profile.codeforces_username = data["codeforces_username"]
user_profile.blog = data["blog"]
user_profile.school = data["school"]
user_profile.phone_number = data["phone_number"]
user_profile.save()
return success_response(u"修改成功")
else:
return serializer_invalid_response(serializer)
class ApplyResetPasswordAPIView(APIView): class ApplyResetPasswordAPIView(APIView):
def post(self, request): def post(self, request):
""" """
@@ -300,28 +333,6 @@ def user_index_page(request, username):
return render(request, "oj/account/user_index.html", {"user": user, "blog_link": blog_link}) return render(request, "oj/account/user_index.html", {"user": user, "blog_link": blog_link})
class UserProfileAPIView(APIView):
@login_required
def put(self, request):
serializer = EditUserProfileSerializer(data=request.data)
if serializer.is_valid():
data = serializer.data
user_profile = request.user.userprofile
if data["avatar"]:
user_profile.avatar = data["avatar"]
user_profile.mood = data["mood"]
user_profile.hduoj_username = data["hduoj_username"]
user_profile.bestcoder_username = data["bestcoder_username"]
user_profile.codeforces_username = data["codeforces_username"]
user_profile.blog = data["blog"]
user_profile.save()
return success_response(u"修改成功")
else:
return serializer_invalid_response(serializer)
class SSOAPIView(APIView): class SSOAPIView(APIView):
def post(self, request): def post(self, request):
serializer = SSOSerializer(data=request.data) serializer = SSOSerializer(data=request.data)

View File

@@ -290,6 +290,8 @@ class MakeContestProblemPublicAPIView(APIView):
hint=problem.hint, created_by=problem.created_by, hint=problem.hint, created_by=problem.created_by,
time_limit=problem.time_limit, memory_limit=problem.memory_limit, time_limit=problem.time_limit, memory_limit=problem.memory_limit,
visible=False, difficulty=-1, source=problem.contest.title) visible=False, difficulty=-1, source=problem.contest.title)
problem.is_public = True
problem.save()
return success_response(u"创建成功") return success_response(u"创建成功")
@@ -424,7 +426,7 @@ def contest_list_page(request, page=1):
@check_user_contest_permission @check_user_contest_permission
def contest_rank_page(request, contest_id): def contest_rank_page(request, contest_id):
contest = Contest.objects.get(id=contest_id) contest = Contest.objects.get(id=contest_id)
contest_problems = ContestProblem.objects.filter(contest=contest).order_by("sort_index") contest_problems = ContestProblem.objects.filter(contest=contest, visible=True).order_by("sort_index")
r = get_cache_redis() r = get_cache_redis()
cache_key = str(contest_id) + "_rank_cache" cache_key = str(contest_id) + "_rank_cache"

View File

@@ -7,17 +7,19 @@ require(["jquery", "bsAlert", "csrfToken", "validator"], function ($, bsAlert, c
var codeforces_username = $("#codeforces_username").val(); var codeforces_username = $("#codeforces_username").val();
var blog = $("#blog").val(); var blog = $("#blog").val();
var mood = $("#mood").val(); var mood = $("#mood").val();
var school = $("#school").val();
$.ajax({ $.ajax({
beforeSend: csrfTokenHeader, beforeSend: csrfTokenHeader,
url: "/api/account/userprofile/", url: "/api/account/userprofile/",
data: { data: {
phone: phone, phone_number: phone,
hduoj_username: hduoj_username, hduoj_username: hduoj_username,
bestcoder_username: bestcoder_username, bestcoder_username: bestcoder_username,
codeforces_username: codeforces_username, codeforces_username: codeforces_username,
blog: blog, blog: blog,
mood: mood mood: mood,
school: school
}, },
dataType: "json", dataType: "json",
method: "put", method: "put",
@@ -38,3 +40,4 @@ require(["jquery", "bsAlert", "csrfToken", "validator"], function ($, bsAlert, c
} }
}); });
}); });

View File

@@ -1,41 +1,61 @@
{% extends "oj_base.html" %} {% extends "oj_base.html" %}
{% block title %} {% block title %}
用户修改密码 用户设置
{% endblock %} {% endblock %}
{% block body %} {% block body %}
<div class="container main"> <div class="container main">
<div class="col-md-6 col-md-offset-3">
<h2 class="text-center">修改密码</h2>
<form id="change_password-form"> <div class="col-lg-2">
<div class="form-group"> <ul class="list-group">
<label for="password">旧密码</label> <li class="list-group-header">通用设置</li>
<input type="password" class="form-control input-lg" id="password" name="password" placeholder="密码" data-error="请填写旧密码" maxlength="30" required> <li class="list-group-item"><a href="/account/settings/">个人信息</a></li>
<div class="help-block with-errors"></div> <li class="list-group-item"><a href="/account/settings/avatar/">更换头像</a></li>
</div> <li class="list-group-item active"><a href="/change_password/">修改密码</a></li>
<div class="form-group"> </ul>
<label for="new_password">新密码</label>
<input type="password" class="form-control input-lg" id="new_password" name="new_password" placeholder="新密码" maxlength="30" data-minlength="6" data-error="密码不得少于6位" required>
<div class="help-block with-errors"></div>
</div>
<div class="form-group">
<label for="confirm_password">确认密码</label>
<input type="password" class="form-control input-lg" id="confirm_password" name="confirm_password" placeholder="确认密码" maxlength="30" data-match="#new_password" data-match-error="两个密码不一致" required>
<div class="help-block with-errors"></div>
</div>
<div class="form-group">
<label for="captcha">验证码</label>
&nbsp;&nbsp;<img src="/captcha/" id="captcha-img">
<small><p></p></small>
<input type="text" class="form-control input-lg" id="captcha" name="captcha" placeholder="验证码" maxlength="4" data-error="请填写验证码" required>
<div class="help-block with-errors"></div>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary">提交</button>
</div>
</form>
</div>
</div> </div>
<div class="col-lg-3">
<img src="https://coding.net/static/fruit_avatar/Fruit-1.png" class="img-responsive"
style="height: 200px;width: 200px;">
</div>
<div class="col-lg-6">
<form id="change_password-form">
<div class="form-group">
<label for="password">旧密码</label>
<input type="password" class="form-control input-lg" id="password" name="password" placeholder="密码"
data-error="请填写旧密码" maxlength="30" required>
<div class="help-block with-errors"></div>
</div>
<div class="form-group">
<label for="new_password">新密码</label>
<input type="password" class="form-control input-lg" id="new_password" name="new_password"
placeholder="新密码" maxlength="30" data-minlength="6" data-error="密码不得少于6位" required>
<div class="help-block with-errors"></div>
</div>
<div class="form-group">
<label for="confirm_password">确认密码</label>
<input type="password" class="form-control input-lg" id="confirm_password" name="confirm_password"
placeholder="确认密码" maxlength="30" data-match="#new_password" data-match-error="两个密码不一致" required>
<div class="help-block with-errors"></div>
</div>
<div class="form-group">
<label for="captcha">验证码</label>
&nbsp;&nbsp;<img src="/captcha/" id="captcha-img">
<small><p></p></small>
<input type="text" class="form-control input-lg" id="captcha" name="captcha" placeholder="验证码"
maxlength="4" data-error="请填写验证码" required>
<div class="help-block with-errors"></div>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary">提交</button>
</div>
</form>
</div>
</div>
</div>
{% endblock %} {% endblock %}
{% block js_block %} {% block js_block %}
<script src="/static/js/app/oj/account/changePassword.js"></script> <script src="/static/js/app/oj/account/changePassword.js"></script>

View File

@@ -1,87 +1,97 @@
{% extends "oj_base.html" %} {% extends "oj_base.html" %}
{% block title %} {% block title %}
用户设置 用户设置
{% endblock %} {% endblock %}
{% block body %} {% block body %}
<div class="container main"> <div class="container main">
<div class="col-lg-2"> <div class="col-lg-2">
<ul class="list-group"> <ul class="list-group">
<li class="list-group-header">通用设置</li> <li class="list-group-header">通用设置</li>
<li class="list-group-item active"><a href="/account/settings/">个人信息</a></li> <li class="list-group-item active"><a href="/account/settings/">个人信息</a></li>
<li class="list-group-item"><a href="/account/settings/avatar/">更换头像</a></li> <li class="list-group-item"><a href="/account/settings/avatar/">更换头像</a></li>
<li class="list-group-item"><a href="/change_password/">修改密码</a></li> <li class="list-group-item"><a href="/change_password/">修改密码</a></li>
</ul> </ul>
</div> </div>
<div class="col-lg-3"> <div class="col-lg-3">
<img src="{{ user.userprofile.avatar }}" class="img-responsive index-avatar"> <img src="{{ user.userprofile.avatar }}" class="img-responsive index-avatar">
</div> </div>
<div class="col-lg-6"> <div class="col-lg-6">
<form> <form>
<div class="row"> <div class="row">
<div class="form-group col-md-6"><label>用户名</label> <div class="form-group col-md-6"><label>用户名</label>
<input name="username" type="text" class="form-control" <input name="username" type="text" class="form-control"
value="{{ request.user.username }}" readonly> value="{{ request.user.username }}" readonly>
</div>
<div class="form-group col-md-6"><label>真实姓名</label>
<input name="real_name" type="text" class="form-control"
value="{{ request.user.real_name }}" readonly>
</div>
</div> </div>
<div class="row"> <div class="form-group col-md-6"><label>真实姓名</label>
<div class="form-group col-md-6"><label>电子邮箱</label> <input name="real_name" type="text" class="form-control"
<input name="email" type="email" class="form-control" value="{{ request.user.real_name }}" readonly>
value="{{ request.user.email }}" readonly> </div>
</div> </div>
<div class="form-group col-md-6"><label>手机</label> <div class="row">
<input name="phone" type="text" maxlength="11" id="phone" <div class="form-group col-md-6"><label>电子邮箱</label>
class="form-control" value="{% if request.user.userprofile.phone %}{{ request.user.userprofile.phone }}{% endif %}"> <input name="email" type="email" class="form-control"
</div> value="{{ request.user.email }}" readonly>
</div>
<div class="form-group col-md-6"><label>手机</label>
<input name="phone" type="text" maxlength="11" id="phone"
class="form-control"
value="{{ request.user.userprofile.phone_number }}">
</div>
<div class="help-block with-errors"></div>
</div>
<div class="row">
<div class="form-group col-md-6">
<label>学校</label>
<input name="school" type="text" class="form-control" id="school"
value="{{ request.user.userprofile.school }}">
<div class="help-block with-errors"></div> <div class="help-block with-errors"></div>
</div> </div>
<div class="row"> <div class="form-group col-md-6">
<label>hduoj 用户名</label>
<input name="hduoj" type="text" class="form-control" id="hduoj_username"
value="{{ request.user.userprofile.hduoj_username }}">
<div class="form-group col-md-6"> <div class="help-block with-errors"></div>
<label>hduoj 用户名</label> </div>
<input name=hduoj" type="text" class="form-control" id="hduoj_username" <div class="form-group col-md-6">
value="{% if request.user.userprofile.hduoj_username %}{{ request.user.userprofile.hduoj_username }}{% endif %}"> <label>BestCoder 用户名</label>
<input name="bestcoder" type="text" class="form-control" id="bestcoder_username"
value="{{ request.user.userprofile.bestcoder_username }}">
<div class="help-block with-errors"></div> <div class="help-block with-errors"></div>
</div> </div>
<div class="form-group col-md-6"> <div class="form-group col-md-6">
<label>BestCoder 用户名</label> <label>Codeforces 用户名</label>
<input name=bestcoder" type="text" class="form-control" id="bestcoder_username" <input name="codeforces" type="text" class="form-control" id="codeforce_username"
value="{% if request.user.userprofile.bestcoder_username %}{{ request.user.userprofile.bestcoder_username }}{% endif %}"> value="{{ request.user.userprofile.bestcoder_username }}">
<div class="help-block with-errors"></div> <div class="help-block with-errors"></div>
</div> </div>
<div class="form-group col-md-6"> <div class="form-group col-md-12"><label>blog</label>
<label>Codeforces 用户名</label> <input name="blog" type="url" class="form-control" id="blog"
<input name=codeforces" type="text" class="form-control" id="codeforces_username" value="{{ request.user.userprofile.blog }}">
value="{% if request.user.userprofile.codeforces_username %}{{ request.user.userprofile.codeforces_username }}{% endif %}">
<div class="help-block with-errors"></div> <div class="help-block with-errors"></div>
</div>
<div class="form-group col-md-12"><label>blog</label>
<input name=blog" type="url" class="form-control" id="blog"
value="{% if request.user.userprofile.blog %}{{ request.user.userprofile.blog }}{% endif %}" data-error="请填写正确的网址">
<div class="help-block with-errors"></div> </div>
</div> <div class="form-group col-md-12">
<div class="form-group col-md-12"><label>签名</label> <label>签名</label>
<input name=mood" type="text" maxlength="60" class="form-control" id="mood" <input name="mood" type="text" maxlength="60" class="form-control" id="mood"
value="{% if request.user.userprofile.mood %}{{ request.user.userprofile.mood }}{% endif %}" data-error="字数限制在30字以内"> value="{% if request.user.userprofile.mood %}{{ request.user.userprofile.mood }}{% endif %}"
data-error="字数限制在30字以内">
<div class="help-block with-errors"></div> <div class="help-block with-errors"></div>
</div>
</div> </div>
<div class="form-group"> <div class="form-group">
<button type="submit" class="btn btn-primary">提交</button> <button type="submit" class="btn btn-primary">提交</button>
</div> </div>
</form> </div>
</div> </form>
</div> </div>
</div>
{% endblock %} {% endblock %}
{% block js_block %} {% block js_block %}