面向用户开发界面(完结)

面向用户开发界面

1.使用functionView

2.使用class-basedView

使用functionView

合理编排url

根据上次的需求有博客首页,博文详情页,分类列表页,标签列表页,友链展示页

决定的url可以有:

  1. 博客首页:127.0.0.1:8080
  2. 博文详情页:127.0.0.1:8080/post/.html
  3. 分类列表页:127.0.0.1:8080/category//
  4. 标签列表页:127.0.0.1:8080/tag/
  5. 友链展示页:127.0.0.1:8080/links

定义相关的url

在urls.py中代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# view相当于视图控制层
from blog.views import post_detail, post_list

from config.views import links

urlpatterns = [
url(r'^admin/', custom_site.urls),
url(r'^super_admin/',admin.site.urls),

url(r'^$',post_list),
# 代表定义了一个组,匹配后面的\d+
url(r'^category/(?P<category_id>\d+)/$',post_list),
url(r'^tag/(?P<tag_id>\d+)/$',post_list),
url(r'^post/(?P<post_id>\d+).html$',post_detail),
url(r'^links/$',links)
]

完整的url参数:

url(正则表达式字符串,视图函数,固定参数,此url的名称)

编写相关View的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14

# Create your views here.
from django.http import HttpResponse

# 这个函数暂时现在可以处理种类和标签的请求
def post_list(request, category_id=None,tag_id=None):
content = 'post _list category_id={category_id}, tag_id={tag_id}'.format(
category_id = category_id,
tag_id = tag_id
)
return HttpResponse(content)

def post_detail(request, post_id):
return HttpResponse('detail')

render基础用法

1
2
3
4
5
def  post_list(request, category_id=None,tag_id=None):
return render(request,'blog/list.html',context={'name':'post_list'})

def post_detail(request, post_id):
return render(request,'blog/detail.html',context={'name':'post_detail'})

render一共6个参数:

  1. request对象
  2. 模版名称
  3. 字典类型数据,可以传递到模版中
  4. 页面编码类型
  5. 状态码
  6. 使用哪种模版引擎解析

配置模版

image-20210226101505726

编写相应的页面和逻辑

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 这个函数暂时现在可以处理种类和标签的请求
def post_list(request, category_id=None,tag_id=None):
if tag_id:
try:
tag = Tag.objects.get(id=tag_id)
except Tag.DoesNotExist:
post_list = []
else:
post_list = tag.post_set.filter(status=Post.STATUS_NORMAL) # eles代表程序正常执行一样执行
# post_set是反向生成了一个外键名字叫xxx_set
else:
post_list = Post.objects.filter(status=Post.STATUS_NORMAL)
if category_id:
post_list = post_list.filter(category_id=category_id)


return render(request,'blog/list.html',context={'post_list':post_list})

def post_detail(request, post_id):
try:
post = Post.objects.get(id=post_id)
except Post.DoesNotExist:
post = None

return render(request,'blog/detail.html',context={'post': post})

页面展示为

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<!--list.html -->
<ul>
{% for post in post_list %}
<li>
<a href="/post/{{ post.id }}.html">{{ post.title }}</a>
<div>
<span>作者:{{ post.owner.username }}</span>
<span>分类:{{ post.category.name }}</span>
</div>
<p>{{ post.desc }}</p>
</li>
{% endfor %}
</ul>
<!--detail.html -->
{% if post %}
<h1>{{ post.title }}</h1>
<div>
<span>作者:{{ post.owner.username }}</span>
<span>分类:{{ post.category.name }}</span>
</div>
<hr/>
<p>
{{ post.content }}
</p>
{% endif %}

image-20210226150123228

image-20210226150144753

重构页面视图

可以在模型中构建api方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
@staticmethod
def get_by_tag(tag_id):
try:
tag = Tag.objects.get(id=tag_id)
except Tag.DoesNotExist:
tag = None
post_list =[]
else:
post_list = tag.post_set.filter(status=Post.STATUS_NORMAL)\
.select_related('owner','category')
return post_list, tag

@staticmethod
def get_by_category(category_id):
try:
category = Category.objects.get(id=category_id)
except Category.DoesNotExist:
category = None
post_list = []
else:
post_list = category.post_set.filter(status=Post.STATUS_NORMAL)\
.select_related('owner','category')

@classmethod
def latest_posts(cls):
queryset = cls.Objects.filter(status=cls.STATUS_NORMAL)
return queryset
# 参考文章 https://blog.csdn.net/guanmaoning/article/details/106746740
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 这个函数暂时现在可以处理种类和标签的请求
def post_list(request, category_id=None,tag_id=None):
tag = None
category = None
if tag_id:
post_list, tag = Post.get_by_tag(tag_id)
elif category_id:
post_list, category = Post.get_by_category(category_id)
else:
post_list = Post.latest_posts()
context = {
'category': category,
'tag': tag,
'post_list': post_list
}

其余页面代码大同小异

关于注解属性的文章可以参考 https://zhuanlan.zhihu.com/p/64487092

关于渲染不同的数据到不同的页面中,可以参考一下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
def content_html(self):
""" 通过直接渲染模板 """
from blog.models import Post # 避免循环引用
from comment.models import Comment

result = ''
if self.display_type == self.DISPLAY_HTML:
result = self.content
elif self.display_type == self.DISPLAY_LATEST:
context = {
'posts': Post.latest_posts()
}
result = render_to_string('config/blocks/sidebar_posts.html', context)
elif self.display_type == self.DISPLAY_HOT:
context = {
'posts': Post.hot_posts()
}
result = render_to_string('config/blocks/sidebar_posts.html', context)
elif self.display_type == self.DISPLAY_COMMENT:
context = {
'comments': Comment.objects.filter(status=Comment.STATUS_NORMAL)
}
result = render_to_string('config/blocks/sidebar_comments.html', context)
return result

整理模版代码

抽象基础模版

抽象出base.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>博客系统</title>
</head>
<body>
<div>顶部分类:
{% for cate in navs %}
<a href="/category/{{ cate.id }}">{{ cate.name}}</a>
{% endfor %}
</div>
<hr/>
{% block main %}
{% endblock %}
<hr/>
<div>底部分类:
{% for cate in navs %}
<a href="/category/{{ cate.id }}">{{ cate.name}}</a>
{% endfor %}
</div>
<div>侧边栏展示:
{% for sidebar in sidebars %}
<h4>{{ sidebar.title }}</h4>
{{ sidebar.content_html }}
{% endfor %}

</div>
</body>
</html>

其余代码参考如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
{% extends './base.html' %}
{% block title %}
{% if tag %}
标签页: {{ tag.name}}
{% endif %}
{% endblock %}

{% block main %}
{% if category %}
分类页: {{ category.name}}
{% endif %}
<ul>
{% for post in post_list %}
<li>
<a href="/post/{{ post.id }}.html">{{ post.title }}</a>
<div>
<span>作者:{{ post.owner.username }}</span>
<span>分类:{{ post.category.name }}</span>
</div>
<p>{{ post.desc }}</p>
</li>
{% endfor %}
</ul>
{% endblock %}

关于url解耦

1
2
3
url(r'^post/(?P<post_id>\d+).html$',post_detail name='post-detail'),

<a href="{% url 'post-detail' post.id %}">{{ post.title }}</a>

使用class-based view

https://www.cnblogs.com/donghaiming/p/11007505.html 分页参考代码如下

https://blog.csdn.net/bibinGee/article/details/104859388 关于类视图 当然可以查阅书籍159-163

https://blog.csdn.net/pyrans/article/details/82763314 使用静态资源参考

https://www.cnblogs.com/sch01ar/p/11508002.html 关于django定义中间件

关于restframwork和一些其他的包插件等,可以到官方市场和博客中查阅

感言

关于django,一个项目需要流程化,比如工作流等特别定制等,除此之外基本都可以考虑使用djangoAdmin来解决

关于django的学习成本主要在djangoAdmin和ORM上。如果需要自行画页面就需要加上django的模版

关于部署和java保持一致。加载类似tomcat的服务器。然后用nginx做分流