Skip to content

Commit

Permalink
Merge pull request Hopetree#224 from Hopetree/add-resume
Browse files Browse the repository at this point in the history
添加个人简历app
  • Loading branch information
Hopetree authored May 5, 2023
2 parents e4d0b1e + 46f4497 commit f851d51
Show file tree
Hide file tree
Showing 17 changed files with 479 additions and 19 deletions.
12 changes: 6 additions & 6 deletions apps/blog/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ def get_object(self):
# 设置浏览量增加时间判断,同一篇文章两次浏览超过半小时才重新统计阅览量,作者浏览忽略
u = self.request.user
ses = self.request.session
the_key = 'is_read_{}'.format(obj.id)
the_key = self.context_object_name + ':read:{}'.format(obj.id)
is_read_time = ses.get(the_key)
if u != obj.author:
if not is_read_time:
Expand All @@ -81,9 +81,9 @@ def get_object(self):
ses[the_key] = time.time()
# 获取文章更新的时间,判断是否从缓存中取文章的markdown,可以避免每次都转换
ud = obj.update_date.strftime("%Y%m%d%H%M%S")
md_key = '{}_md_{}'.format(obj.id, ud)
md_key = self.context_object_name + ':markdown:{}:{}'.format(obj.id, ud)
cache_md = cache.get(md_key)
if cache_md:
if cache_md and settings.DEBUG is False:
obj.body, obj.toc = cache_md
else:
md = markdown.Markdown(extensions=[
Expand All @@ -94,7 +94,7 @@ def get_object(self):
])
obj.body = md.convert(obj.body)
obj.toc = md.toc
cache.set(md_key, (obj.body, obj.toc), 60 * 60 * 12)
cache.set(md_key, (obj.body, obj.toc), 3600 * 24 * 7)
return obj


Expand Down Expand Up @@ -156,9 +156,9 @@ def AboutView(request):
obj = AboutBlog.objects.first()
if obj:
ud = obj.update_date.strftime("%Y%m%d%H%M%S")
md_key = '{}_md_{}'.format(obj.id, ud)
md_key = 'about:markdown:{}:{}'.format(obj.id, ud)
cache_md = cache.get(md_key)
if cache_md:
if cache_md and settings.DEBUG is False:
body = cache_md
else:
body = obj.body_to_markdown()
Expand Down
1 change: 1 addition & 0 deletions apps/resume/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
default_app_config = 'resume.apps.ResumeConfig'
54 changes: 54 additions & 0 deletions apps/resume/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
from django.apps import apps
from django.conf import settings
from django.contrib import admin

from .models import Resume, ResumeTemplate


# Register your models here.

@admin.register(ResumeTemplate)
class ResumeTemplateAdmin(admin.ModelAdmin):
# 在查看修改的时候显示的属性,第一个字段带有<a>标签,所以最好放标题
list_display = ('id', 'name', 'description')

# 设置需要添加<a>标签的字段
list_display_links = ('name',)

# 限制用户权限,只能超管可以编辑
def get_queryset(self, request):
qs = super(ResumeTemplateAdmin, self).get_queryset(request)
if request.user.is_superuser:
return qs
return None


@admin.register(Resume)
class ResumeAdmin(admin.ModelAdmin):
# 这个的作用是给出一个筛选机制,一般按照时间比较好
date_hierarchy = 'create_date'

# 在查看修改的时候显示的属性,第一个字段带有<a>标签,所以最好放标题
list_display = ('id', 'title', 'author', 'create_date', 'update_date', 'is_open')

# 设置需要添加<a>标签的字段
list_display_links = ('title',)

# 激活过滤器,这个很有用
list_filter = ('create_date', 'is_open')

# 限制用户权限,只能看到自己编辑的简历
def get_queryset(self, request):
qs = super(ResumeAdmin, self).get_queryset(request)
if request.user.is_superuser:
return qs
return qs.filter(author=request.user)

def formfield_for_foreignkey(self, db_field, request, **kwargs):
User = apps.get_model(settings.AUTH_USER_MODEL)
if db_field.name == 'author':
if request.user.is_superuser:
kwargs['queryset'] = User.objects.filter(is_staff=True, is_active=True)
else:
kwargs['queryset'] = User.objects.filter(id=request.user.id)
return super(ResumeAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
6 changes: 6 additions & 0 deletions apps/resume/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from django.apps import AppConfig


class ResumeConfig(AppConfig):
name = 'resume'
verbose_name = '简历管理'
50 changes: 50 additions & 0 deletions apps/resume/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Generated by Django 2.2.27 on 2023-05-05 13:37

from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

initial = True

dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]

operations = [
migrations.CreateModel(
name='ResumeTemplate',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=20, verbose_name='模板名称')),
('description', models.TextField(max_length=240, verbose_name='描述')),
('content', models.TextField(verbose_name='css内容')),
],
options={
'verbose_name': '简历模板',
'verbose_name_plural': '简历模板',
'ordering': ['name'],
},
),
migrations.CreateModel(
name='Resume',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('title', models.CharField(max_length=150, verbose_name='简历标题')),
('body', models.TextField(verbose_name='简历内容')),
('create_date', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('update_date', models.DateTimeField(auto_now=True, verbose_name='修改时间')),
('slug', models.SlugField(unique=True, verbose_name='访问地址')),
('is_open', models.BooleanField(default=False, verbose_name='是否公开')),
('author', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL, verbose_name='作者')),
('template', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='resume.ResumeTemplate', verbose_name='简历模板')),
],
options={
'verbose_name': '个人简历',
'verbose_name_plural': '个人简历',
'ordering': ['-create_date'],
},
),
]
Empty file.
46 changes: 46 additions & 0 deletions apps/resume/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
from django.db import models
from django.conf import settings
from django.shortcuts import reverse


# Create your models here.

class ResumeTemplate(models.Model):
name = models.CharField('模板名称', max_length=20)
description = models.TextField('描述', max_length=240)
content = models.TextField('css内容')

class Meta:
verbose_name = '简历模板'
verbose_name_plural = verbose_name
ordering = ['name']

def __str__(self):
return self.name


# 个人简历
class Resume(models.Model):
author = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name='作者',
on_delete=models.PROTECT)
title = models.CharField(max_length=150, verbose_name='简历标题')
body = models.TextField(verbose_name='简历内容')
create_date = models.DateTimeField(verbose_name='创建时间', auto_now_add=True)
update_date = models.DateTimeField(verbose_name='修改时间', auto_now=True)
slug = models.SlugField('访问地址', unique=True)
is_open = models.BooleanField('是否公开', default=False)

template = models.ForeignKey(ResumeTemplate, verbose_name='简历模板', on_delete=models.PROTECT)

class Meta:
verbose_name = '个人简历'
verbose_name_plural = verbose_name
ordering = ['-create_date']

def __str__(self):
if len(self.title) > 20:
return self.title[:20] + '...'
return self.title

def get_absolute_url(self):
return reverse('resume:detail', kwargs={'slug': self.slug})
8 changes: 8 additions & 0 deletions apps/resume/static/resume/css/detail.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.flex-container {
display: flex;
}

.flex-container .left {
flex: auto;
text-align: left;
}
30 changes: 30 additions & 0 deletions apps/resume/templates/resume/base.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{% load static %}
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="referrer" content="origin">
<!-- TDK and ICO -->
<title>{% block head_title %}{% endblock %}</title>
{% block metas %}
{% endblock %}
<link rel="icon"
href="data:image/svg+xml,<svg xmlns=%22https://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%221em%22 font-size=%22100%22>🐠</text></svg>">
<!-- Bootstrap and font-awesome CSS -->
<link href="https://cdn.bootcss.com/twitter-bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet">
<link href="https://cdn.bootcss.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
<!-- blog CSS -->
{% block top-file %}{% endblock %}
</head>
<body>
<!--主要内容块-->
<main>{% block base_content %}{% endblock %}</main>
<!-- Optional JavaScript -->
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.bootcss.com/twitter-bootstrap/4.3.1/js/bootstrap.min.js"></script>
{% block end_file %}{% endblock %}
</body>
</html>
50 changes: 50 additions & 0 deletions apps/resume/templates/resume/detail.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
{% extends 'resume/base.html' %}
{% load static %}

{% block head_title %}个人简历{% endblock %}

{% block top-file %}
<link href="{% static 'resume/css/detail.css' %}?v=20230505.02" rel="stylesheet">
<!-- 加载主题css -->
<style>{{ resume.template.content }}</style>
<style>
/* 打印样式 */
@media print {
.page {
page-break-inside: avoid; /* 尝试在元素内部不进行分页 */
page-break-after: always; /* 在元素之后添加分页符 */
}
}
</style>
{% endblock %}

{% block base_content %}
<div class="container">
<div class="row justify-content-center">
<div class="col-lg-9 col-xl-10">
<div class="page">{{ resume.body|safe }}</div>
</div>
</div>
</div>
{% endblock %}

{% block end_file %}
<script>
window.onload = function () {
// 获取页面高度
var pageHeight = window.innerHeight;

// 获取内容高度
var pageElements = document.getElementsByClassName('page');
for (var i = 0; i < pageElements.length; i++) {
var pageElement = pageElements[i];
var pageContentHeight = pageElement.offsetHeight;

// 如果内容高度大于页面高度则插入分页符
if (pageContentHeight > pageHeight) {
pageElement.style.pageBreakAfter = 'always';
}
}
}
</script>
{% endblock %}
51 changes: 51 additions & 0 deletions apps/resume/tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
from django.test import TestCase
import markdown

from .utils import FlexExtension, BoxExtension, IconExtension

# Create your tests here.

text = """
A regular paragraph of text.
::::
:::left
icon:info 男/1995.12
icon:weixin qiufengblue
:::
::: right
icon:info 男/1995.12
icon:weixin qiufengblue
:::
::::
Another regular paragraph of text.
"""


class MarkdownTests(TestCase):
def test_flex_extension(self):
md = markdown.Markdown(extensions=[
FlexExtension(),
])
print(md.convert(text))

def test_box_extension(self):
md = markdown.Markdown(extensions=[
BoxExtension(),
])
html = md.convert(text)
print(html)

def test_icon_extension(self):
md = markdown.Markdown(extensions=[
IconExtension(),
])
html = md.convert(text)
print(html)
8 changes: 8 additions & 0 deletions apps/resume/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# -*- coding: utf-8 -*-
from django.urls import path

from .views import ResumeDetailView

urlpatterns = [
path('<slug:slug>/', ResumeDetailView.as_view(), name='detail')
]
Loading

0 comments on commit f851d51

Please sign in to comment.