migrate to postgres json field

This commit is contained in:
zema1 2017-10-11 21:43:29 +08:00
parent 93bd77d8d8
commit 080ecf1bcf
15 changed files with 315 additions and 27 deletions

View File

@ -0,0 +1,105 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.4 on 2017-10-11 12:14
from __future__ import unicode_literals
import django.contrib.postgres.fields.jsonb
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('account', '0007_auto_20170920_0254'),
]
operations = [
migrations.RemoveField(
model_name='userprofile',
name='language',
),
migrations.AlterField(
model_name='user',
name='admin_type',
field=models.CharField(default='Regular User', max_length=32),
),
migrations.AlterField(
model_name='user',
name='auth_token',
field=models.CharField(max_length=32, null=True),
),
migrations.AlterField(
model_name='user',
name='email',
field=models.EmailField(max_length=64, null=True),
),
migrations.AlterField(
model_name='user',
name='open_api_appkey',
field=models.CharField(max_length=32, null=True),
),
migrations.AlterField(
model_name='user',
name='problem_permission',
field=models.CharField(default='None', max_length=32),
),
migrations.AlterField(
model_name='user',
name='reset_password_token',
field=models.CharField(max_length=32, null=True),
),
migrations.AlterField(
model_name='user',
name='session_keys',
field=django.contrib.postgres.fields.jsonb.JSONField(default=list),
),
migrations.AlterField(
model_name='user',
name='tfa_token',
field=models.CharField(max_length=32, null=True),
),
migrations.AlterField(
model_name='user',
name='username',
field=models.CharField(max_length=32, unique=True),
),
migrations.AlterField(
model_name='userprofile',
name='acm_problems_status',
field=django.contrib.postgres.fields.jsonb.JSONField(default=dict),
),
migrations.AlterField(
model_name='userprofile',
name='avatar',
field=models.CharField(default='/static/avatar/default.png', max_length=256),
),
migrations.AlterField(
model_name='userprofile',
name='github',
field=models.CharField(blank=True, max_length=64, null=True),
),
migrations.AlterField(
model_name='userprofile',
name='major',
field=models.CharField(blank=True, max_length=64, null=True),
),
migrations.AlterField(
model_name='userprofile',
name='mood',
field=models.CharField(blank=True, max_length=256, null=True),
),
migrations.AlterField(
model_name='userprofile',
name='oi_problems_status',
field=django.contrib.postgres.fields.jsonb.JSONField(default=dict),
),
migrations.AlterField(
model_name='userprofile',
name='real_name',
field=models.CharField(blank=True, max_length=32, null=True),
),
migrations.AlterField(
model_name='userprofile',
name='school',
field=models.CharField(blank=True, max_length=64, null=True),
),
]

View File

@ -1,7 +1,7 @@
from django.contrib.auth.models import AbstractBaseUser from django.contrib.auth.models import AbstractBaseUser
from django.conf import settings from django.conf import settings
from django.db import models from django.db import models
from jsonfield import JSONField from utils.models import JSONField
class AdminType(object): class AdminType(object):
@ -36,7 +36,7 @@ class User(AbstractBaseUser):
auth_token = models.CharField(max_length=32, null=True) auth_token = models.CharField(max_length=32, null=True)
two_factor_auth = models.BooleanField(default=False) two_factor_auth = models.BooleanField(default=False)
tfa_token = models.CharField(max_length=32, null=True) tfa_token = models.CharField(max_length=32, null=True)
session_keys = JSONField(default=[]) session_keys = JSONField(default=list)
# open api key # open api key
open_api = models.BooleanField(default=False) open_api = models.BooleanField(default=False)
open_api_appkey = models.CharField(max_length=32, null=True) open_api_appkey = models.CharField(max_length=32, null=True)
@ -65,11 +65,20 @@ class User(AbstractBaseUser):
class UserProfile(models.Model): class UserProfile(models.Model):
user = models.OneToOneField(User) user = models.OneToOneField(User)
# Store user problem solution status with json string format # acm_problems_status examples:
# {problems: {1: JudgeStatus.ACCEPTED}, contest_problems: {1: JudgeStatus.ACCEPTED}}, record problem_id and status # {
acm_problems_status = JSONField(default={}) # "problems": {
# {problems: {1: 33}, contest_problems: {1: 44}, record problem_id and score # "1": {
oi_problems_status = JSONField(default={}) # "status": JudgeStatus.ACCEPTED,
# "_id": "1000"
# }
# },
# "contest_problems": {
# }
# }
acm_problems_status = JSONField(default=dict)
# like acm_problems_status, merely add "score" field
oi_problems_status = JSONField(default=dict)
real_name = models.CharField(max_length=32, blank=True, null=True) real_name = models.CharField(max_length=32, blank=True, null=True)
avatar = models.CharField(max_length=256, default=f"/{settings.IMAGE_UPLOAD_DIR}/default.png") avatar = models.CharField(max_length=256, default=f"/{settings.IMAGE_UPLOAD_DIR}/default.png")

View File

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.4 on 2017-10-11 12:14
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('announcement', '0001_initial'),
]
operations = [
migrations.AlterField(
model_name='announcement',
name='title',
field=models.CharField(max_length=64),
),
]

View File

@ -0,0 +1,39 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.4 on 2017-10-11 12:14
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('conf', '0001_initial'),
]
operations = [
migrations.DeleteModel(
name='JudgeServerToken',
),
migrations.DeleteModel(
name='SMTPConfig',
),
migrations.DeleteModel(
name='WebsiteConfig',
),
migrations.AlterField(
model_name='judgeserver',
name='hostname',
field=models.CharField(max_length=128),
),
migrations.AlterField(
model_name='judgeserver',
name='judger_version',
field=models.CharField(max_length=32),
),
migrations.AlterField(
model_name='judgeserver',
name='service_url',
field=models.CharField(blank=True, max_length=256, null=True),
),
]

View File

@ -0,0 +1,26 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.4 on 2017-10-11 12:14
from __future__ import unicode_literals
import django.contrib.postgres.fields.jsonb
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('contest', '0005_auto_20170823_0918'),
]
operations = [
migrations.AlterField(
model_name='acmcontestrank',
name='submission_info',
field=django.contrib.postgres.fields.jsonb.JSONField(default=dict),
),
migrations.AlterField(
model_name='oicontestrank',
name='submission_info',
field=django.contrib.postgres.fields.jsonb.JSONField(default=dict),
),
]

View File

@ -1,7 +1,7 @@
from utils.constants import ContestRuleType # noqa from utils.constants import ContestRuleType # noqa
from django.db import models from django.db import models
from django.utils.timezone import now from django.utils.timezone import now
from jsonfield import JSONField from utils.models import JSONField
from utils.constants import ContestStatus, ContestType from utils.constants import ContestStatus, ContestType
from account.models import User, AdminType from account.models import User, AdminType
@ -65,7 +65,7 @@ class ACMContestRank(AbstractContestRank):
total_time = models.IntegerField(default=0) total_time = models.IntegerField(default=0)
# {23: {"is_ac": True, "ac_time": 8999, "error_number": 2, "is_first_ac": True}} # {23: {"is_ac": True, "ac_time": 8999, "error_number": 2, "is_first_ac": True}}
# key is problem id # key is problem id
submission_info = JSONField(default={}) submission_info = JSONField(default=dict)
class Meta: class Meta:
db_table = "acm_contest_rank" db_table = "acm_contest_rank"
@ -75,7 +75,7 @@ class OIContestRank(AbstractContestRank):
total_score = models.IntegerField(default=0) total_score = models.IntegerField(default=0)
# {23: 333}} # {23: 333}}
# key is problem id, value is current score # key is problem id, value is current score
submission_info = JSONField(default={}) submission_info = JSONField(default=dict)
class Meta: class Meta:
db_table = "oi_contest_rank" db_table = "oi_contest_rank"

View File

@ -186,13 +186,10 @@ class JudgeDispatcher(object):
# update user_profile # update user_profile
if problem_id not in acm_problems_status: if problem_id not in acm_problems_status:
acm_problems_status[problem_id] = self.submission.result acm_problems_status[problem_id] = {"status": self.submission.result, "_id": self.problem._id}
# skip if the problem has been accepted # skip if the problem has been accepted
elif acm_problems_status[problem_id] != JudgeStatus.ACCEPTED: elif acm_problems_status[problem_id]["status"] != JudgeStatus.ACCEPTED:
if self.submission.result == JudgeStatus.ACCEPTED: acm_problems_status[problem_id]["status"] = self.submission.result
acm_problems_status[problem_id] = JudgeStatus.ACCEPTED
else:
acm_problems_status[problem_id] = self.submission.result
user_profile.acm_problems_status[key] = acm_problems_status user_profile.acm_problems_status[key] = acm_problems_status
else: else:
@ -204,11 +201,14 @@ class JudgeDispatcher(object):
# update user_profile # update user_profile
if problem_id not in oi_problems_status: if problem_id not in oi_problems_status:
user_profile.add_score(score) user_profile.add_score(score)
oi_problems_status[problem_id] = score oi_problems_status[problem_id] = {"status": self.submission.result,
"_id": self.problem._id,
"score": score}
else: else:
# minus last time score, add this time score # minus last time score, add this time score
user_profile.add_score(this_time_score=score, last_time_score=oi_problems_status[problem_id]) user_profile.add_score(this_time_score=score, last_time_score=oi_problems_status[problem_id]["score"])
oi_problems_status[problem_id] = score oi_problems_status[problem_id]["score"] = score
oi_problems_status[problem_id]["status"] = self.submission.result
user_profile.oi_problems_status[key] = oi_problems_status user_profile.oi_problems_status[key] = oi_problems_status
problem.save(update_fields=["submission_number", "accepted_number", "statistic_info"]) problem.save(update_fields=["submission_number", "accepted_number", "statistic_info"])

View File

@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.4 on 2017-10-11 12:14
from __future__ import unicode_literals
import django.contrib.postgres.fields.jsonb
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('options', '0001_initial'),
]
operations = [
migrations.AlterField(
model_name='sysoptions',
name='value',
field=django.contrib.postgres.fields.jsonb.JSONField(),
),
]

View File

@ -1,5 +1,5 @@
from django.db import models from django.db import models
from jsonfield import JSONField from utils.models import JSONField
class SysOptions(models.Model): class SysOptions(models.Model):

View File

@ -0,0 +1,41 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.4 on 2017-10-11 12:14
from __future__ import unicode_literals
import django.contrib.postgres.fields.jsonb
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('problem', '0008_auto_20170923_1318'),
]
operations = [
migrations.AlterField(
model_name='problem',
name='languages',
field=django.contrib.postgres.fields.jsonb.JSONField(),
),
migrations.AlterField(
model_name='problem',
name='samples',
field=django.contrib.postgres.fields.jsonb.JSONField(),
),
migrations.AlterField(
model_name='problem',
name='statistic_info',
field=django.contrib.postgres.fields.jsonb.JSONField(default=dict),
),
migrations.AlterField(
model_name='problem',
name='template',
field=django.contrib.postgres.fields.jsonb.JSONField(),
),
migrations.AlterField(
model_name='problem',
name='test_case_score',
field=django.contrib.postgres.fields.jsonb.JSONField(),
),
]

View File

@ -1,5 +1,5 @@
from django.db import models from django.db import models
from jsonfield import JSONField from utils.models import JSONField
from account.models import User from account.models import User
from contest.models import Contest from contest.models import Contest
@ -66,7 +66,7 @@ class Problem(models.Model):
submission_number = models.BigIntegerField(default=0) submission_number = models.BigIntegerField(default=0)
accepted_number = models.BigIntegerField(default=0) accepted_number = models.BigIntegerField(default=0)
# ACM rule_type: {JudgeStatus.ACCEPTED: 3, JudgeStaus.WRONG_ANSWER: 11}, the number means count # ACM rule_type: {JudgeStatus.ACCEPTED: 3, JudgeStaus.WRONG_ANSWER: 11}, the number means count
statistic_info = JSONField(default={}) statistic_info = JSONField(default=dict)
class Meta: class Meta:
db_table = "problem" db_table = "problem"

View File

@ -55,9 +55,9 @@ class ProblemAPI(APIView):
oi_problems_status = profile.oi_problems_status.get("problems", {}) oi_problems_status = profile.oi_problems_status.get("problems", {})
for problem in data["results"]: for problem in data["results"]:
if problem["rule_type"] == ProblemRuleType.ACM: if problem["rule_type"] == ProblemRuleType.ACM:
problem["my_status"] = acm_problems_status.get(str(problem["id"]), None) problem["my_status"] = acm_problems_status.get(str(problem["id"]), {}).get("status")
else: else:
problem["my_status"] = oi_problems_status.get(str(problem["id"]), None) problem["my_status"] = oi_problems_status.get(str(problem["id"]), {}).get("status")
return self.success(data) return self.success(data)

View File

@ -0,0 +1,26 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.4 on 2017-10-11 12:14
from __future__ import unicode_literals
import django.contrib.postgres.fields.jsonb
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('submission', '0007_auto_20170923_1318'),
]
operations = [
migrations.AlterField(
model_name='submission',
name='info',
field=django.contrib.postgres.fields.jsonb.JSONField(default=dict),
),
migrations.AlterField(
model_name='submission',
name='statistic_info',
field=django.contrib.postgres.fields.jsonb.JSONField(default=dict),
),
]

View File

@ -1,5 +1,5 @@
from django.db import models from django.db import models
from jsonfield import JSONField from utils.models import JSONField
from account.models import AdminType from account.models import AdminType
from problem.models import Problem from problem.models import Problem
from contest.models import Contest from contest.models import Contest
@ -31,12 +31,12 @@ class Submission(models.Model):
code = models.TextField() code = models.TextField()
result = models.IntegerField(db_index=True, default=JudgeStatus.PENDING) result = models.IntegerField(db_index=True, default=JudgeStatus.PENDING)
# 判题结果的详细信息 # 判题结果的详细信息
info = JSONField(default={}) info = JSONField(default=dict)
language = models.CharField(max_length=20) language = models.CharField(max_length=20)
shared = models.BooleanField(default=False) shared = models.BooleanField(default=False)
# 存储该提交所用时间和内存值,方便提交列表显示 # 存储该提交所用时间和内存值,方便提交列表显示
# {time_cost: "", memory_cost: "", err_info: "", score: 0} # {time_cost: "", memory_cost: "", err_info: "", score: 0}
statistic_info = JSONField(default={}) statistic_info = JSONField(default=dict)
def check_user_permission(self, user): def check_user_permission(self, user):
return self.user_id == user.id or \ return self.user_id == user.id or \

View File

@ -1,3 +1,4 @@
from django.contrib.postgres.fields import JSONField # NOQA
from django.db import models from django.db import models
from utils.xss_filter import XssHtml from utils.xss_filter import XssHtml