Skip to content

Commit 9f6cd31

Browse files
committed
增加了拥有复制和自动生成密码的表单字段PasswordFormField.
1 parent b0acf2b commit 9f6cd31

File tree

7 files changed

+204
-4
lines changed

7 files changed

+204
-4
lines changed

README.md

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@ pip install /path/to/your_project/dist/DjangoAsyncAdmin-6.5.4.tar.gz
4343
| 目录 | 备注 |
4444
|-----------------|----------|
4545
| bawa |
46-
| components |
47-
| editor |
46+
| components |组件,存放模型字段和表单字段
47+
| editor |编辑器,MD编辑器,UE富文本编辑器,JSON编辑器等等
4848
| group |
4949
| locale |多种语言包目录,明文和二进制文件不需要处理
5050
| management |
@@ -75,6 +75,15 @@ pip install /path/to/your_project/dist/DjangoAsyncAdmin-6.5.4.tar.gz
7575
<td>版本</td><td colspan="2">说明</td>
7676
</tr>
7777

78+
<tr>
79+
<td rowspan="2">6.7.1</td>
80+
<td colspan="2">增加了拥有复制和自动生成密码的表单字段模型. 可以通过 `from simplepro.components.forms import PasswordFormField` 来引入调用.</td>
81+
</tr>
82+
<tr>
83+
<td colspan="2"><img src="docs/static/截屏2023-11-15%2016.20.58.png"/></td>
84+
</tr>
85+
86+
7887
<tr>
7988
<td>6.7.0</td>
8089
<td colspan="2">增加了基本类BaseModel和BaseModelWithShowRate,减少开发过程中反复进行一些基本字段和属性的设计, 提高设计模型的效率.</td>

docs/build.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# 打包及发布教程
2+
3+
##### 1.生成安装包
4+
进入到项目跟目录
5+
6+
```shell
7+
python setup.py sdist bdist_wheel
8+
```
9+
10+
#### 2.安装
11+
12+
```shell
13+
pip install /path/to/your_project/dist/DjangoAsyncAdmin-6.5.4.tar.gz
14+
```
15+
#### 3.发布
16+
```shell
17+
twain
18+
```
18.4 KB
Loading

pyproject.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "DjangoAsyncAdmin"
3-
version = "6.7.0"
3+
version = "6.7.1"
44
authors = [
55
{ name = "Sadam·Sadik", email = "1903249375@qq.com" },
66
]
@@ -17,7 +17,6 @@ classifiers = [
1717
"Homepage" = "https://haoke98.github.io/DjangoAsyncAdmin/"
1818
"Bug Tracker" = "https://github.com/Haoke98/DjangoAsyncAdmin/issues"
1919
"Documentation" = "https://haoke98.github.io/DjangoAsyncAdmin/"
20-
"Documentation" = "https://www.mldoo.com/docs/simplepro/"
2120
"Demo" = "https://github.com/Haoke98/AllKeeper"
2221

2322
[build-system]

simplepro/components/forms.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# _*_ codign:utf8 _*_
2+
"""====================================
3+
@Author:Sadam·Sadik
4+
@Email:1903249375@qq.com
5+
@Date:2023/11/15
6+
@Software: PyCharm
7+
@disc:
8+
======================================="""
9+
from django import forms
10+
from simplepro.components.widgets import PasswordInput
11+
12+
13+
class PasswordFormField(forms.CharField):
14+
pattern: str
15+
lenMin: int
16+
lenMax: int
17+
encryptByMd5: bool
18+
19+
def __init__(self, widget=PasswordInput, encryptByMd5: bool = True, lenMin: int = 6, lenMax: int = 48,
20+
pattern: str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-$%&@+!", *args,
21+
**kwargs):
22+
self.pattern = pattern
23+
self.lenMin = lenMin
24+
self.lenMax = lenMax
25+
self.encryptByMd5 = encryptByMd5
26+
super().__init__(widget=widget, *args, **kwargs)
27+
28+
def widget_attrs(self, widget):
29+
attrs = super().widget_attrs(widget)
30+
if isinstance(widget, PasswordInput):
31+
attrs['pattern'] = self.pattern
32+
attrs['lenMin'] = self.lenMin
33+
attrs['lenMax'] = self.lenMax
34+
attrs['encryptByMd5'] = self.encryptByMd5
35+
return attrs

simplepro/components/widgets.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from django import forms
66
from django.db.models import QuerySet, Manager
77
from django.db.models.base import ModelBase
8+
from django.template import loader
89
from django.template.loader import render_to_string
910
from django.utils import formats
1011

@@ -406,6 +407,18 @@ def trim_name(name):
406407
return name.replace('-', '_')
407408

408409

410+
class PasswordInput(forms.TextInput):
411+
template_name = "admin/components/password_input.html"
412+
413+
def __init__(self, *args, **kwargs):
414+
super().__init__(*args, **kwargs)
415+
416+
def render(self, name, value, attrs=None, renderer=None):
417+
context = self.get_context(name, value, attrs)
418+
template = loader.get_template(self.template_name).render(context)
419+
return mark_safe(template)
420+
421+
409422
class SelectInput(forms.Widget, Input):
410423
choices = ()
411424
template_name = 'admin/components/select.html'
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
<head>
2+
<!-- 引入样式 -->
3+
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
4+
<!-- 引入组件库 -->
5+
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
6+
<!--MD5加密-->
7+
<script src="https://cdn.bootcss.com/blueimp-md5/2.10.0/js/md5.js"></script>
8+
</head>
9+
<style type="text/css">
10+
.el-upload-list {
11+
margin-left: 0px !important;
12+
}
13+
14+
.v_{{ widget.attrs.id }} {
15+
display: inline-block;
16+
}
17+
18+
.v_{{ widget.attrs.id }} ul {
19+
margin-left: 0px;
20+
padding-left: 0px;
21+
}
22+
23+
.v_{{ widget.attrs.id }} .el-upload-dragger {
24+
width: auto;
25+
height: auto;
26+
border: none;
27+
}
28+
29+
em {
30+
color: #ff0000;
31+
background-color: rgba(8, 61, 0, 0);
32+
font-style: normal;
33+
}
34+
</style>
35+
<template id="v_{{ widget.attrs.id }}">
36+
<div class="v_{{ widget.attrs.id }}">
37+
{# <el-button type="info" size="small" @click="copy">复制</el-button>#}
38+
{# <el-button type="primary" size="small" @click="reset">手动修改</el-button>#}
39+
{# <el-button type="success" size="small" @click="generate">随机生成</el-button>#}
40+
<input name="{{ widget.name }}" :value="value" style="display: none" type="text">
41+
<el-input v-model="value" placeholder="请设置密码" :maxlength="lenMax" :minlength="lenMin" show-word-limit
42+
show-password clearable size="small" width="200" step="0" validate-event="true">
43+
<el-button slot="prepend" @click="generate" type="success">随机生成</el-button>
44+
{# <el-button slot="append" @click="reset" type="primary" icon="el-icon-edit">手动修改</el-button>#}
45+
<el-button slot="append" @click="copy" type="info" icon="el-icon-document-copy">复制</el-button>
46+
</el-input>
47+
</div>
48+
</template>
49+
<script type="text/javascript">
50+
var app_{{ widget.name }} = new Vue({
51+
el: '#v_{{ widget.attrs.id }}',
52+
data: {
53+
value: {% if widget.value is None %}''
54+
{% endif %}{% if widget.value is not None %}'{{ widget.value }}'{% endif %},
55+
lenMin: {% if widget.attrs.lenMin is None %}8
56+
{% endif %}{% if widget.attrs.lenMin is not None %}{{ widget.attrs.lenMin }}{% endif %},
57+
lenMax: {% if widget.attrs.lenMax is None %}16
58+
{% endif %}{% if widget.attrs.lenMax is not None %}{{ widget.attrs.lenMax }}{% endif %},
59+
pwdPattern: '{{ widget.attrs.pattern }}'
60+
},
61+
methods: {
62+
reset() {
63+
let _this = this;
64+
this.$prompt('请输入新的密码', '密码重置', {
65+
confirmButtonText: '确定',
66+
cancelButtonText: '取消',
67+
inputPattern: /.{8,16}/,
68+
inputErrorMessage: '密码格式不正确'
69+
}).then(({value}) => {
70+
this.$message({
71+
type: 'success',
72+
message: '重置成功,请及时点击保存,否则重置将无效!'
73+
});
74+
this.value = value;
75+
{% if widget.attrs.encryptByMd5 %}
76+
//进行MD5加密,再放到form表单中
77+
this.value = md5(value);
78+
{% endif %}
79+
}).catch(() => {
80+
this.$message({
81+
type: 'info',
82+
message: '密码重置被取消'
83+
});
84+
});
85+
},
86+
87+
generate() {
88+
this.value = '';
89+
let len = Math.ceil((this.lenMax + this.lenMin) / 2);
90+
console.log(this.lenMin,this.lenMax,"随机生成密码的长度为:",len);
91+
for (let i = 0; i < len; i++) {
92+
let x = Math.floor(Math.random() * this.pwdPattern.length);
93+
this.value += this.pwdPattern[x];
94+
}
95+
{% if widget.attrs.encryptByMd5 %}
96+
//进行MD5加密,再放到form表单中
97+
this.value = md5(this.value);
98+
{% endif %}
99+
},
100+
copy() {
101+
if (this.value === ''||this.value ===undefined){
102+
this.$message({
103+
type: 'warn',
104+
message: '密码是空的'
105+
});
106+
}else{
107+
copyStr(this.value)
108+
this.$message({
109+
type: 'success',
110+
message: '复制成功!'
111+
});
112+
}
113+
}
114+
},
115+
});
116+
117+
function copyStr(str) {
118+
var oInput = document.createElement('input');
119+
oInput.value = str;
120+
document.body.appendChild(oInput);
121+
oInput.select(); // 选择对象
122+
document.execCommand("Copy"); // 执行浏览器复制命令
123+
oInput.className = 'oInput';
124+
oInput.style.display = 'none';
125+
}
126+
</script>

0 commit comments

Comments
 (0)