Skip to content

Commit 49fcfb8

Browse files
lflxplixueping
authored andcommitted
完成主功能开发 完善readme文档
0 parents  commit 49fcfb8

File tree

108 files changed

+19118
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

108 files changed

+19118
-0
lines changed

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
tmp/
2+
# *.crt
3+
# *.key
4+
.DS_Store
5+
upload/

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2024 lflxp
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

Makefile

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
run:
2+
cd examples && go run example.go
3+
4+
swag:
5+
swag init --parseDependency --parseDepth=1
6+
7+
sample:
8+
cd examples/sample && go run main.go

README.md

Lines changed: 340 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,340 @@
1+
# 介绍
2+
3+
`本项目的目的是利用django的admin设计模式 + gin + golang实现应用的快读搭建和使用,免去搭建底层框架的困扰,自动生成CRUD的界面,节能增效`
4+
5+
Django 是一款流行的 Python Web 框架,提供了丰富的功能和灵活的配置选项,使得开发者可以快速地构建高质量、可扩展的 Web 应用程序。而 Golang 版本的 Django 框架 Django-Golang,则是将 Django 框架用 Golang 语言重新实现的一个版本,具有更高的运行时性能和更好的并发支持。
6+
7+
Django-Golang 的特点:
8+
9+
1. 高性能:Django-Golang 使用 Golang 语言编写,具有更高的运行时性能,可以快速地处理请求和响应。
10+
11+
2. 并发支持:Django-Golang 支持并发编程,可以轻松地编写多线程程序,提高程序的并发性能。
12+
13+
3. 灵活的配置:Django-Golang 提供了灵活的配置选项,开发者可以根据自己的需求进行自定义。
14+
15+
4. 丰富的功能:Django-Golang 继承了 Django 框架强大的功能,包括 ORM、模板引擎、表单、管理员等功能。
16+
17+
安装 Django-Golang:
18+
19+
1. 安装 Golang:可以从官方网站(https://golang.org/dl/)下载适合自己操作系统的安装包,然后按照官方文档的指引进行安装。
20+
21+
2. 安装 Django-Golang:在命令行中输入以下命令即可:
22+
```
23+
go get https://github.com/lflxp/djangolangexamples
24+
```
25+
这将下载 Django-Golang 并将其安装到你的 Golang 环境中。
26+
27+
使用 Django-Golang:
28+
29+
1. djangolangexamples 项目包含一个Demo App,里面包含一个一对多的模型和完整的Swagger API:在命令行中输入以下命令即可:
30+
```
31+
cd djangolangexamples
32+
go mod tidy
33+
go run main.go
34+
```
35+
这将创建一个新的 Django-Golang 项目,其中 `myproject` 是你的项目名称。
36+
37+
2. 设置 Django-Golang 项目配置:`main.go`中配置如下:
38+
```
39+
// 是否开启https访问
40+
isHttps bool = true
41+
// 设置服务host
42+
Host string = "0.0.0.0"
43+
// 设置服务端口
44+
Port string = "8000"
45+
// 是否开启自动打开浏览器
46+
OpenBrowser bool = true
47+
```
48+
这将启动 Django-Golang 项目,并在默认的端口 8000 上运行。
49+
50+
3. 创建 Django-Golang 接口注册和其它配置:在 `main.go` 文件中,可以定义 Django-Golang 配置,例如:
51+
```
52+
// 设置跨域设置
53+
r.Use(middlewares.Cors())
54+
// 设置恢复策略
55+
r.Use(gin.Recovery())
56+
// 设置日志
57+
r.Use(gin.Logger())
58+
// 设置健康检查接口
59+
r.GET("/health", middlewares.RegisterHealthMiddleware)
60+
// 设置swagger
61+
middlewares.RegisterSwaggerMiddleware(r)
62+
// 注册demo和vpn接口
63+
demo.RegisterDemo(r)
64+
demo.RegisterVpn(r)
65+
// 设置自动跳转
66+
r.GET("/", func(c *gin.Context) {
67+
c.Redirect(301, "/admin/index")
68+
})
69+
70+
// 注册admin接口
71+
djangolang.RegisterControllerAdmin(r)
72+
// r.Run() // listen and serve on 0.0.0.0:8080 (for windows "localhost:8080")
73+
74+
// 配置gin优雅启动
75+
var server *http.Server
76+
```
77+
78+
4. Admin视图适配,表结构字段解析
79+
80+
以下是djangolangexamples包含的两个数据结构: Demo和Vpn
81+
82+
```go
83+
type Demo struct {
84+
Id int64 `xorm:"id pk not null autoincr" name:"id" search:"true"`
85+
Country string `json:"country" xorm:"varchar(255) not null" search:"true"`
86+
Zoom string `json:"zoom" xorm:"varchar(255) not null"`
87+
Company string `json:"company" xorm:"varchar(255) not null"`
88+
Items string `json:"items" xorm:"varchar(255) not null"`
89+
Production string `json:"production" xorm:"varchar(255) not null"`
90+
Count string `json:"count" xorm:"varchar(255) not null"`
91+
Serial string `json:"serial" xorm:"varchar(255) not null" search:"true"`
92+
Extend string `json:"extend" xorm:"varchar(255) not null"`
93+
Files string `xorm:"file" name:"file" verbose_name:"上传文件" colType:"file"`
94+
File2 string `xorm:"file2" name:"file2" verbose_name:"上传文件2" colType:"file"`
95+
Type string `xorm:"type" name:"type" verbose_name:"类型" search:"false" colType:"textarea"`
96+
Detail string `xorm:"detail" name:"detail" verbose_name:"VPN信息" list:"false" search:"false" o2m:"vpn|id,vpn" colType:"o2m"`
97+
Times time.Time `xorm:"times" name:"times" verbose_name:"时间" colType:"time" list:"true" search:"true"`
98+
}
99+
100+
type Vpn struct {
101+
Id int64 `xorm:"id notnull unique pk autoincr" name:"id"`
102+
Vpn string `xorm:"vpn" name:"vpn" verbose_name:"Vpn字段测试" list:"true" search:"true"`
103+
Name string `xorm:"name" name:"name" verbose_name:"姓名" list:"true" search:"false"`
104+
Ip string `xorm:"ip" name:"ip" verbose_name:"ip信息" list:"true" search:"false"`
105+
}
106+
107+
```
108+
109+
其中注释字段解析字段如下:
110+
111+
| 字段名 | 字段描述 | 类型 | 是否必须 | 显示效果 | 备注 |
112+
| ---- | ---- | ---- | ---- | ---- | ---- |
113+
| xorm | 数据库字段 | string ||| xorm框架定义数据库字段,`id notnull unique pk autoincr` 表示id字段 不为空 唯一性 主键 字增字段 |
114+
| json | json字段显示 | string ||| - |
115+
| name | 显示字段 | string ||| admin自动框架表单字段 |
116+
| verbose_name | 表单显示名称 | string ||| form表单显示名称 |
117+
| search | 是否支持搜索 | bool ||| 设置是否是table页面搜索框支持字段 |
118+
| colType | 字段类型 | string || 表单字段类型,有:`textarea` `file` `o2m` `int,int16,int64` `string` `text` `select` `radio` `multiselect` `time` `o2o` `m2m` `password` |
119+
| list | 是否表格显示 | bool ||| 表格字段是否显示 |
120+
| o2m | 一对多关系设置 | string ||| 设置一对多的表及pk外键,如: vpn|id,vpn |
121+
122+
Django-Golang 的配置选项非常丰富,可以根据自己的需求进行自定义。此外,Django-Golang 还提供了丰富的第三方库支持,可以方便地集成第三方库到项目中,例如:数据库、缓存、队列等。
123+
124+
总结:Django-Golang 是一个将 Django 框架用 Golang 语言重新实现的高性能 Web 框架,具有更高的运行时性能和更好的并发支持,非常适合开发高质量、可扩展的 Web 应用程序。如果你想要使用 Golang 构建 Web 应用程序,Django-Golang 是一个不错的选择。
125+
126+
# Install
127+
128+
## 快速安装
129+
130+
> cd examples/sample && go run main.go
131+
132+
## 全功能
133+
134+
> cd examples/allinone && go run example.go
135+
136+
## 完整演示项目
137+
138+
参考 [djangolangexamples](github.com/lflxp/djangolangexamples)
139+
140+
# 功能详情
141+
142+
首先使用github.com/lflxp/djangolang很简单,下面是一个Demo
143+
144+
```go
145+
package main
146+
147+
import (
148+
"github.com/lflxp/djangolang"
149+
"time"
150+
151+
"github.com/gin-gonic/gin"
152+
)
153+
154+
type Demotest2 struct {
155+
Id int64 `xorm:"id pk not null autoincr" name:"id" search:"true"`
156+
Country string `json:"country" xorm:"varchar(255) not null" search:"true"`
157+
Zoom string `json:"zoom" xorm:"varchar(255) not null"`
158+
Company string `json:"company" xorm:"varchar(255) not null"`
159+
Items string `json:"items" xorm:"varchar(255) not null"`
160+
Production string `json:"production" xorm:"varchar(255) not null"`
161+
Count string `json:"count" xorm:"varchar(255) not null"`
162+
Serial string `json:"serial" xorm:"varchar(255) not null" search:"true"`
163+
Extend string `json:"extend" xorm:"varchar(255) not null"`
164+
Files string `xorm:"file" name:"file" verbose_name:"上传文件" colType:"file"`
165+
Times time.Time `xorm:"times" name:"times" verbose_name:"时间" colType:"time" list:"true" search:"true"`
166+
}
167+
168+
func init() {
169+
djangolang.RegisterAdmin(new(Demotest2))
170+
}
171+
172+
func main() {
173+
r := gin.Default()
174+
r.GET("/", func(c *gin.Context) {
175+
c.Redirect(301, "/admin/index")
176+
})
177+
178+
djangolang.RegisterControllerAdmin(r)
179+
r.Run() // listen and serve on 0.0.0.0:8080 (for windows "localhost:8080")
180+
}
181+
```
182+
183+
高级功能展示
184+
185+
```go
186+
package main
187+
188+
import (
189+
"crypto/tls"
190+
"crypto/x509"
191+
"github.com/lflxp/djangolang"
192+
"github.com/lflxp/djangolang/middlewares"
193+
ctls "github.com/lflxp/djangolang/tls"
194+
"github.com/lflxp/djangolang/utils"
195+
"fmt"
196+
"net/http"
197+
"os"
198+
"os/signal"
199+
200+
"github.com/gin-contrib/gzip"
201+
"github.com/gin-gonic/gin"
202+
log "github.com/go-eden/slf4go"
203+
"github.com/skratchdot/open-golang/open"
204+
)
205+
206+
var GinEngine *gin.Engine
207+
208+
type Args struct {
209+
Host string
210+
Port string
211+
IsHttps bool
212+
OpenBrowser bool
213+
Auth struct {
214+
Url string
215+
IdentityKey string
216+
Dev bool
217+
}
218+
}
219+
220+
func Run(args *Args) {
221+
// gin.SetMode(gin.ReleaseMode)
222+
GinEngine = gin.Default()
223+
224+
// 注册路由
225+
226+
GinEngine.Use(gin.Logger())
227+
GinEngine.Use(gin.Recovery())
228+
GinEngine.Use(middlewares.Cors())
229+
GinEngine.Use(gzip.Gzip(gzip.DefaultCompression, gzip.WithExcludedPathsRegexs([]string{".*"})))
230+
// GinEngine.Use(middlewares.NoRouteHandler)
231+
GinEngine.GET("/health", middlewares.RegisterHealthMiddleware)
232+
GinEngine.GET("/", func(c *gin.Context) {
233+
c.Redirect(301, "/admin/index")
234+
})
235+
Registertest(GinEngine)
236+
djangolang.RegisterControllerAdmin(GinEngine)
237+
log.Infof("ip %s port %s", args.Host, args.Port)
238+
239+
if args.Host == "" {
240+
// instance.Fatal("Check Host or Port config already!!!")
241+
args.Host = "0.0.0.0"
242+
}
243+
244+
if args.Port == "" {
245+
args.Port = "8002"
246+
}
247+
248+
var server *http.Server
249+
if args.IsHttps {
250+
err := ctls.Refresh()
251+
if err != nil {
252+
panic(err)
253+
}
254+
255+
pool := x509.NewCertPool()
256+
caCeretPath := "ca.crt"
257+
258+
caCrt, err := os.ReadFile(caCeretPath)
259+
if err != nil {
260+
panic(err)
261+
}
262+
263+
pool.AppendCertsFromPEM(caCrt)
264+
265+
server = &http.Server{
266+
Addr: fmt.Sprintf("%s:%s", args.Host, args.Port),
267+
Handler: GinEngine,
268+
TLSConfig: &tls.Config{
269+
ClientCAs: pool,
270+
ClientAuth: tls.RequestClientCert,
271+
},
272+
}
273+
} else {
274+
server = &http.Server{
275+
Addr: fmt.Sprintf("%s:%s", args.Host, args.Port),
276+
Handler: GinEngine,
277+
}
278+
279+
}
280+
281+
quit := make(chan os.Signal)
282+
signal.Notify(quit, os.Interrupt)
283+
284+
go func() {
285+
<-quit
286+
log.Warn("receive interrupt signal")
287+
if err := server.Close(); err != nil {
288+
log.Fatal("Server Close:", err)
289+
}
290+
}()
291+
292+
var openUrl string
293+
for index, ip := range utils.GetIPs() {
294+
if args.IsHttps {
295+
log.Infof("Listening and serving HTTPS on https://%s:%s", ip, args.Port)
296+
} else {
297+
log.Infof("Listening and serving HTTPS on http://%s:%s", ip, args.Port)
298+
}
299+
300+
if index == 0 {
301+
openUrl = fmt.Sprintf("%s:%s", ip, args.Port)
302+
}
303+
}
304+
if args.IsHttps {
305+
if args.OpenBrowser {
306+
open.Start(fmt.Sprintf("https://%s", openUrl))
307+
}
308+
if err := server.ListenAndServeTLS("ca.crt", "ca.key"); err != nil {
309+
if err == http.ErrServerClosed {
310+
log.Warn("Server closed under request")
311+
} else {
312+
log.Fatalf("Server closed unexpect %s", err.Error())
313+
}
314+
}
315+
} else {
316+
if args.OpenBrowser {
317+
open.Start(fmt.Sprintf("http://%s", openUrl))
318+
}
319+
if err := server.ListenAndServe(); err != nil {
320+
if err == http.ErrServerClosed {
321+
log.Warn("Server closed under request")
322+
} else {
323+
log.Fatalf("Server closed unexpect %s", err.Error())
324+
}
325+
}
326+
}
327+
328+
log.Warn("Server exiting")
329+
}
330+
331+
func main() {
332+
args := Args{
333+
IsHttps: true,
334+
OpenBrowser: true,
335+
Port: "9000",
336+
}
337+
Run(&args)
338+
}
339+
```
340+

0 commit comments

Comments
 (0)