4 Commits
v1.02 ... v1.04

Author SHA1 Message Date
RobbieHan
2bba133771 SystemIndex 2018-10-17 23:27:14 +08:00
RobbieHan
2261bc6b3a workspace 2018-10-17 15:23:04 +08:00
RobbieHan
005b62a01e workspace 2018-10-17 15:22:21 +08:00
RobbieHan
0b04685f2f authenticate 2018-10-17 15:19:17 +08:00
33 changed files with 556 additions and 1227 deletions

4
.idea/sandboxMP.iml generated
View File

@@ -12,7 +12,9 @@
</facet>
</component>
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/apps" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>

1433
.idea/workspace.xml generated

File diff suppressed because it is too large Load Diff

3
apps/__init__.py Normal file
View File

@@ -0,0 +1,3 @@
# @Time : 2018/10/17 14:54
# @Author : RobbieHan
# @File : __init__.py.py

Binary file not shown.

0
apps/system/__init__.py Normal file
View File

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

3
apps/system/admin.py Normal file
View File

@@ -0,0 +1,3 @@
from django.contrib import admin
# Register your models here.

5
apps/system/apps.py Normal file
View File

@@ -0,0 +1,5 @@
from django.apps import AppConfig
class SystemConfig(AppConfig):
name = 'apps.system'

10
apps/system/forms.py Normal file
View File

@@ -0,0 +1,10 @@
# @Time : 2018/10/17 23:13
# @Author : RobbieHan
# @File : forms.py
from django import forms
class LoginForm(forms.Form):
username = forms.CharField(required=True, error_messages={"requeired": "请填写用户名"})
password = forms.CharField(required=True, error_messages={"requeired": "请填写密码"})

View File

@@ -0,0 +1,112 @@
# Generated by Django 2.1.2 on 2018-10-17 15:09
from django.conf import settings
import django.contrib.auth.models
import django.contrib.auth.validators
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
class Migration(migrations.Migration):
initial = True
dependencies = [
('auth', '0009_alter_user_last_name_max_length'),
]
operations = [
migrations.CreateModel(
name='UserProfile',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('password', models.CharField(max_length=128, verbose_name='password')),
('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')),
('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')),
('username', models.CharField(error_messages={'unique': 'A user with that username already exists.'}, help_text='Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.', max_length=150, unique=True, validators=[django.contrib.auth.validators.UnicodeUsernameValidator()], verbose_name='username')),
('first_name', models.CharField(blank=True, max_length=30, verbose_name='first name')),
('last_name', models.CharField(blank=True, max_length=150, verbose_name='last name')),
('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')),
('is_active', models.BooleanField(default=True, help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', verbose_name='active')),
('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')),
('name', models.CharField(default='', max_length=20, verbose_name='姓名')),
('birthday', models.DateField(blank=True, null=True, verbose_name='出生日期')),
('gender', models.CharField(choices=[('male', ''), ('female', '')], default='male', max_length=10, verbose_name='性别')),
('mobile', models.CharField(default='', max_length=11, verbose_name='手机号码')),
('email', models.EmailField(max_length=50, verbose_name='邮箱')),
('image', models.ImageField(blank=True, default='image/default.jpg', null=True, upload_to='image/%Y/%m')),
('post', models.CharField(blank=True, max_length=50, null=True, verbose_name='职位')),
],
options={
'verbose_name': '用户信息',
'verbose_name_plural': '用户信息',
'ordering': ['id'],
},
managers=[
('objects', django.contrib.auth.models.UserManager()),
],
),
migrations.CreateModel(
name='Menu',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=30, unique=True, verbose_name='菜单名')),
('icon', models.CharField(blank=True, max_length=50, null=True, verbose_name='图标')),
('code', models.CharField(blank=True, max_length=50, null=True, verbose_name='编码')),
('url', models.CharField(blank=True, max_length=128, null=True, unique=True)),
('parent', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='system.Menu', verbose_name='父菜单')),
],
options={
'verbose_name': '菜单',
'verbose_name_plural': '菜单',
},
),
migrations.CreateModel(
name='Role',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=32, unique=True, verbose_name='角色')),
('desc', models.CharField(blank=True, max_length=50, null=True, verbose_name='描述')),
('permissions', models.ManyToManyField(blank=True, to='system.Menu', verbose_name='URL授权')),
],
),
migrations.CreateModel(
name='Structure',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=60, verbose_name='名称')),
('type', models.CharField(choices=[('unit', '单位'), ('department', '部门')], default='department', max_length=20, verbose_name='类型')),
('parent', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='system.Structure', verbose_name='父类架构')),
],
options={
'verbose_name': '组织架构',
'verbose_name_plural': '组织架构',
},
),
migrations.AddField(
model_name='userprofile',
name='department',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='system.Structure', verbose_name='部门'),
),
migrations.AddField(
model_name='userprofile',
name='groups',
field=models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.Group', verbose_name='groups'),
),
migrations.AddField(
model_name='userprofile',
name='roles',
field=models.ManyToManyField(blank=True, to='system.Role', verbose_name='角色'),
),
migrations.AddField(
model_name='userprofile',
name='superior',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL, verbose_name='上级主管'),
),
migrations.AddField(
model_name='userprofile',
name='user_permissions',
field=models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.Permission', verbose_name='user permissions'),
),
]

View File

12
apps/system/mixin.py Normal file
View File

@@ -0,0 +1,12 @@
# @Time : 2018/10/17 15:15
# @Author : RobbieHan
# @File : mixin.py.py
from django.contrib.auth.decorators import login_required
class LoginRequiredMixin(object):
@classmethod
def as_view(cls, **init_kwargs):
view = super(LoginRequiredMixin, cls).as_view(**init_kwargs)
return login_required(view)

73
apps/system/models.py Normal file
View File

@@ -0,0 +1,73 @@
from django.db import models
from django.contrib.auth.models import AbstractUser
class Menu(models.Model):
"""
菜单
"""
name = models.CharField(max_length=30, unique=True, verbose_name="菜单名") # unique=True, 这个字段在表中必须有唯一值.
parent = models.ForeignKey("self", null=True, blank=True, on_delete=models.SET_NULL, verbose_name="父菜单")
icon = models.CharField(max_length=50, null=True, blank=True, verbose_name="图标")
code = models.CharField(max_length=50, null=True, blank=True, verbose_name="编码")
url = models.CharField(max_length=128, unique=True, null=True, blank=True)
def __str__(self):
return self.name
class Meta:
verbose_name = '菜单'
verbose_name_plural = verbose_name
@classmethod
def get_menu_by_request_url(cls, url):
return dict(menu=Menu.objects.get(url=url))
class Role(models.Model):
"""
角色:用于权限绑定
"""
name = models.CharField(max_length=32, unique=True, verbose_name="角色")
permissions = models.ManyToManyField("menu", blank=True, verbose_name="URL授权")
desc = models.CharField(max_length=50, blank=True, null=True, verbose_name="描述")
class Structure(models.Model):
"""
组织架构
"""
type_choices = (("unit", "单位"), ("department", "部门"))
name = models.CharField(max_length=60, verbose_name="名称")
type = models.CharField(max_length=20, choices=type_choices, default="department", verbose_name="类型")
parent = models.ForeignKey("self", null=True, blank=True, on_delete=models.SET_NULL, verbose_name="父类架构")
class Meta:
verbose_name = "组织架构"
verbose_name_plural = verbose_name
def __str__(self):
return self.name
class UserProfile(AbstractUser):
name = models.CharField(max_length=20, default="", verbose_name="姓名")
birthday = models.DateField(null=True, blank=True, verbose_name="出生日期")
gender = models.CharField(max_length=10, choices=(("male", ""), ("female", "")),
default="male", verbose_name="性别")
mobile = models.CharField(max_length=11, default="", verbose_name="手机号码")
email = models.EmailField(max_length=50, verbose_name="邮箱")
image = models.ImageField(upload_to="image/%Y/%m", default="image/default.jpg",
max_length=100, null=True, blank=True)
department = models.ForeignKey("Structure", null=True, blank=True, on_delete=models.SET_NULL, verbose_name="部门")
post = models.CharField(max_length=50, null=True, blank=True, verbose_name="职位")
superior = models.ForeignKey("self", null=True, blank=True, on_delete=models.SET_NULL, verbose_name="上级主管")
roles = models.ManyToManyField("role", verbose_name="角色", blank=True)
class Meta:
verbose_name = "用户信息"
verbose_name_plural = verbose_name
ordering = ['id']
def __str__(self):
return self.name

3
apps/system/tests.py Normal file
View File

@@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

9
apps/system/urls.py Normal file
View File

@@ -0,0 +1,9 @@
from django.urls import path
from .views import SystemView
app_name = 'system'
urlpatterns = [
path('', SystemView.as_view(), name='login'),
]

11
apps/system/views.py Normal file
View File

@@ -0,0 +1,11 @@
from django.shortcuts import render
from django.views.generic.base import View
from .mixin import LoginRequiredMixin
class SystemView(LoginRequiredMixin, View):
def get(self, request):
return render(request, 'system/system_index.html')

54
apps/system/views_user.py Normal file
View File

@@ -0,0 +1,54 @@
# @Time : 2018/10/16 23:11
# @Author : RobbieHan
# @File : views_user.py
from django.shortcuts import render
from django.views.generic.base import View
from django.http import HttpResponseRedirect
from django.contrib.auth import authenticate, login, logout
from django.urls import reverse
from .forms import LoginForm
from .mixin import LoginRequiredMixin
class IndexView(LoginRequiredMixin, View):
def get(self, request):
return render(request, 'index.html')
class LoginView(View):
def get(self, request):
if not request.user.is_authenticated:
return render(request, 'system/users/login.html')
else:
return HttpResponseRedirect('/')
def post(self, request):
redirect_to = request.GET.get('next', '/')
login_form = LoginForm(request.POST)
ret = dict(login_form=login_form)
if login_form.is_valid():
user_name = request.POST['username']
pass_word = request.POST['password']
user = authenticate(username=user_name, password=pass_word)
if user is not None:
if user.is_active:
login(request, user)
return HttpResponseRedirect(redirect_to)
else:
ret['msg'] = '用户未激活!'
else:
ret['msg'] = '用户名或密码错误!'
else:
ret['msg'] = '用户和密码不能为空!'
return render(request, 'system/users/login.html', ret)
class LogoutView(View):
def get(self, request):
logout(request)
return HttpResponseRedirect(reverse('login'))

Binary file not shown.

View File

@@ -11,10 +11,12 @@ https://docs.djangoproject.com/en/2.1/ref/settings/
"""
import os
import sys
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, os.path.join(BASE_DIR, 'apps'))
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/2.1/howto/deployment/checklist/
@@ -37,6 +39,7 @@ INSTALLED_APPS = [
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'apps.system.apps.SystemConfig',
]
MIDDLEWARE = [
@@ -51,6 +54,8 @@ MIDDLEWARE = [
ROOT_URLCONF = 'sandboxMP.urls'
AUTH_USER_MODEL = 'system.UserProfile'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
@@ -121,3 +126,9 @@ USE_TZ = False
STATIC_URL = '/static/'
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')]
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
LOGIN_URL = '/login/'

View File

@@ -14,8 +14,25 @@ Including another URLconf
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path
from django.urls import path, include
from django.conf import settings
from django.urls import re_path
from django.views.static import serve
from system.views_user import IndexView, LoginView, LogoutView
urlpatterns = [
path('admin/', admin.site.urls),
path('', IndexView.as_view(), name='index'),
path('login/', LoginView.as_view(), name='login'),
path('logout/', LogoutView.as_view(), name='logout'),
path('system/', include('system.urls', namespace='system')),
]
if settings.DEBUG:
urlpatterns += [
re_path(r'^media/(?P<path>.*)$', serve, {"document_root": settings.MEDIA_ROOT}),
]

View File

@@ -0,0 +1,21 @@
{% extends "base-left.html" %}
{% load staticfiles %}
{% block content %}
<!-- Main content -->
<section class="content">
系统管理首页system_indexcontent是页面定义的主要区域
头部和底部内容以及导航栏都是通过模板继承的,之后的所有
功能前端页面都是在content内进行编辑。
</section>
<!-- /.content -->
{% endblock %}
{% block javascripts %}
{% endblock %}