分类目录归档:技术开发

使用Samba远程挂载Windows共享目录

本文将指导如何通过Samba挂载Windows远程目录实现在CentOS下访问Windows共享文件。

前提条件

CentOS:192.168.1.101
Windows:192.168.1.102
Windows共享目录: S盘

首先安装Samba客户端

yum install -y samba-client

安装完成后,可以用smbclient -L命令查看Windows目录共享情况

smbclient -L //192.168.1.102 -U Administrator
Enter Administrator's password:
Domain=[HYPER-V] OS=[Windows Server 2016 Datacenter 14393] Server=[Windows Server 2016 Datacenter 6.3]

        Sharename       Type      Comment
        ---------       ----      -------
        ADMIN$          Disk      远程管理
        C$              Disk      默认共享
        D$              Disk      默认共享
        IPC$            IPC       远程 IPC
        S$              Disk      默认共享
        T$              Disk      默认共享
Connection to 192.168.1.102 failed (Error NT_STATUS_RESOURCE_NAME_NOT_FOUND)
NetBIOS over TCP disabled -- no workgroup available

这里可以看到我将要共享的磁盘<S:>

接下来创建共享目录

mkdir -p /mnt/share

将远程目录mount到/mnt/share目录上

mount -t cifs -o username="Administrator",password="WIN_PASSWD" //192.168.1.102/S$ /mnt/share/

解释一下上述命令

mount: 挂载命令
-t cifs: 挂载文件格式为cifs(Common Internet File System),通用Internet文件系统
-o username,password: option选项,填写Windows用户名和密码
//192.168.1.102/S$: 远程共享目录//IP/DISK$
/mnt/share: 本地目录

挂载完成后即可直接访问该远程目录了。如果需要断开挂载,只需执行:

umont /mnt/share

挂载的Windows共享文件夹在Linux重启之后就会消失的,如果还要使用,是需要重新挂载的。
如果希望Linux开机自动挂载Windows共享文件夹,则需要将挂载命令添加到Linux的/etc/fstab,也就是将前述的命令参数按照fstab的要求添加到fstab里面。

What‘s More…

可以通过使用Apache达到用浏览器访问此目录的效果。这里给出一个参考配置文件。

<VirtualHost *:80>

    DocumentRoot /mnt/share/CONTENTS/

    <Directory /mnt/share/CONTENTS/>
        Options Indexes FollowSymLinks
        AllowOverride All
        Order allow,deny
        Allow from all
        Require all granted
    </Directory>

    ErrorLog /var/log/httpd/error.log
    CustomLog /var/log/httpd/access.log combined

</VirtualHost>

如果遇到403错误,请确认是否关闭Selinux。

《Spring Boot实战》读书笔记01

还是大学毕设的时候接触过Spring MVC,那时候使用的框架是Spring、Struts2、Mybatis。当时就已经感觉配置起来实在太过麻烦,为了完成一个hello world,在不熟悉的情况下花了一天才把环境勉强搭好。对比世界上最好的语言php,门槛高了太多。以至于之后我第一年工作用php简直不要太舒服。

不过,由于新的工作环境,我又得拾起当年那套java体系,好在技术不断迭代,类似ruby on rails的Spring Boot出现了,据说能减少很多的配置成本。既然准备学习,一本好书是必要的,所以我选择的普遍推荐的《Spring Boot实战》(PDF下载)

首先,安装spring boot cli,书中提到了多种安装方式,由于我是以Windows作为开发环境,所以选择了下载压缩包。这里给出下载地址,在这个页面中选择最新的spring boot cli版本下载即可。我选择的是:

http://repo.spring.io/release/org/springframework/boot/spring-boot-cli/1.5.2.RELEASE/spring-boot-cli-1.5.2.RELEASE-bin.zip

然后添加以下环境变量

在cmd输入spring命令,正确返回版本信息即为成功。

spring --version

IDE我选择的是书中推荐的IntelliJ IDEA,开始下载的Community版本,但是安装后才发现Community版本并不支持Spring Boot。所以还是下载了Ultimate版。很想支持正版,无奈价格实在超出负担,所以选择了自建激活服务器,不是关键内容,这里就不具体说方法了,给个传送门

大概描述就是启动一个授权服务器,然后用supervisor维持服务。贴一个supervisor配置文件:

# /etc/supervisor/conf.d/intellijserver.conf

[program:intellijserver]
command=/usr/bin/intellijserver
autostart=true
autorestart=true
user=root
log_stderr=true
logfile=/var/log/intellijserver.log

考虑到可能使用数据库,我起了一个ubuntu server,安装了mysql-server。

环境已经搞定,下面开始我的第一个spring boot应用。按照书中的方法,创建一个readinglist的应用,创建时选择Spring Initializr:

组件勾选Web、Thymeleaf、JPA、H2

然后,第一个应用就创建成功了

总得来说,虽然还是无法和php、python这种脚本语言相比,但是Spring Boot确实简化了不少操作。

WordPress主题额外CSS的实现

观察到最近的版本中,WordPress在主题自定义页面添加了一个功能:额外CSS。之前许多第三方主题自带了这个功能,而WordPress官方是如何实现这个功能的呢。

首先,主题的配置文件只存在于两处:

  • /wp-content/themes/主题目录/
  • 数据库wp_options表

而此类的输入型属性一般都是在数据库中存储,所以我重点关注了下数据库。执行查询:

select option_id, option_name from wp_options where option_name like "%theme%" order by option_id;

果然找到其中一条关于我正在使用的主题twentyfifteen的记录

+-----------+--------------------------------------------------+
| option_id | option_name              |
+-----------+--------------------------------------------------+
|     32154 | theme_mods_twentyfifteen |

下面我们来看看这条记录具体的内容

select * from wp_options where option_id = 32154;

查到结果中的option_value的值如下:

a:6:{s:18:"nav_menu_locations";a:2:{s:7:"primary";i:6;s:6:"social";i:102;}s:16:"background_color";s:6:"efefef";s:12:"color_scheme";s:7:"default";s:17:"sidebar_textcolor";s:7:"#ffffff";s:23:"header_background_color";s:7:"#303030";s:18:"custom_css_post_id";i:1371;}

这是一条序列化了的记录,不过还是注意到了最后有一个custom_css_post_id,这不就是我们的自定义css吗!key名中含有post id,难道是以文章的形式存储的?于是带着这个id的值”1371″,我到文章表wp_posts中查找。

select post_content from wp_posts where ID = 1371;

得到的内容如下:

html, body, div, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, font, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, input {
        font-family: Microsoft YaHei, Century Gothic !important;
}

果然,真相大白,新版的WordPress中自定义CSS的配置被以文章形式存储在了数据库中。

Django博客系统开发06

用户登录

博客作为内容管理系统(CMS)的一种形式,也应当具有CMS的两个功能:内容管理、权限管理。在之前的几篇中,我们已经实现了内容管理。现在实现用户管理,即用户的登录和登出以及页面权限管理。

首先我们现在一共有以下views: index(), post_view(), post_create(), post_edit(), post_drafts(), post_publish(), post_delete()。在这些views中,出了index()和post_views()这两个属于内容展现的方法以外,其他方法应该都受到登录保护。所以,我们引入django自带的@login_required注解来处理这些方法。

首先在hzblog/views.py中引入login_required,并在需要登录验证的方法前加上注解。

from django.contrib.auth.decorators import login_required

@login_required
def post_create(request):
    ...

@login_required
def post_edit(request, pk):
    ...

@login_required
def post_drafts(request):
    ...

@login_required
def post_publish(request, pk):
    ...

@login_required
def post_delete(request, pk):
    ...

然后,在hzsite/urls.py中引入登录登出的路由。注意,由于整个系统使用统一的登录登出路由,所以这里不是在app的urls.py中引入路由。

from django.contrib.auth import views

urlpatterns = [
    ...
    url(r'^accounts/login/$', views.login, name='login'),
    url(r'^accounts/logout/$', views.logout, name='logout'),
    ...
]

这里,我们还要修改一下hzsite/settings.py配置文件,将login/logout操作后的跳转页面定义到’/’目录,即首页。在settings.py中,加入两行:

LOGIN_REDIRECT_URL = '/'
LOGOUT_REDIRECT_URL = '/'

引入路由之后,我们创建一个登录页面进行登录。创建hzblog/templates/registration/目录,在目录下创建login.html模板

{% extends "blog/base.html" %}

{% block content %}

{% if form.errors %}
<p>Your username and password didn't match. Please try again.</p>
{% endif %}

<form method="post" action="{% url 'login' %}">
{% csrf_token %}
<table>
<tr>
    <td>{{ form.username.label_tag }}</td>
    <td>{{ form.username }}</td>
</tr>
<tr>
    <td>{{ form.password.label_tag }}</td>
    <td>{{ form.password }}</td>
</tr>
</table>

<input type="submit" value="login" />
<input type="hidden" name="next" value="{{ next }}" />
</form>

{% endblock %}

最后,我们修改base.html模板,在头部加上登录登出的按钮

...
    <div class="page-header">
        {% if user.is_authenticated %}
            <a href="{% url 'logout' %}" class="top-menu"><span class="glyphicon glyphicon-log-out"></span></a>
            <a href="{% url 'hzblog:post_create' %}" class="top-menu"><span class="glyphicon glyphicon-plus"></span></a>
            <a href="{% url 'hzblog:post_drafts' %}" class="top-menu"><span class="glyphicon glyphicon-list-alt"></span></a>
            <p class="top-menu">Hello {{ user.username }}</p>
        {% else %}
            <a href="{% url 'login' %}" class="top-menu"><span class="glyphicon glyphicon-log-in"></span></a>
        {% endif %}
        <h1><a href="/">ZIVER'S</a></h1>
    </div>
...

下面运行博客测试一下功能

 python manage.py runserver 0.0.0.0:8080

未登录状态点开首页时,右上角显示登录按钮

1

点击登录或者使用需要登录的功能(修改、删除等),跳转到登录页面

2

输入用户信息登录后,右上角出现欢迎信息和只有登录后才可见的按钮

3

登录功能完美实现。

Django博客系统开发05

文章的增删改发布

通过之前的步骤,我们已经有了一个初步的网站页面(首页+Django Admin),其实我们已经可以通过admin页面来对文章进行操作了,但是为了更像是一个真正的博客,我们应该能够从前端进行对文章的增删改查。

查看文章(post_view)

我们现在只有一个页面–首页。在首页中,我们获取到的是全部已经发布的文章列表。现在,我们创建一个文章详情页,当用户点击首页的文章标题时,将跳转到这个页面。

首先,我们为这个页面添加路由,在hzblog/urls.py中加入一行

url(r'^post/(?P<pk>[0-9]+)/$', views.post_view, name='post_view'),

然后,我们修改模板文件,增加跳转链接。在index.html中修改标题的href属性:

<h1><a href="{% url 'hzblog:post_view' pk=post.pk %}">{{ post.title }}</a></h1>

这里使用了url方法来获得post_view的真实url。hzblog:post_view(即AppName:RouterName)这种写法时因为我们之前在hzblog/urls.py中进行了如下定义:

...
app_name = 'hzblog'

urlpatterns = [
    ...
    url(r'^post/(?P<pk>[0-9]+)/$', views.post_view, name='post_view'),
    ...
]

如果是在hzsite/urls.py中定义的url,则不需要添加app前缀,直接使用’post_views’。

下面,创建列表页对应的view。修改views.py,加入post_view方法:

from django.shortcuts import render, get_object_or_404

def post_view(request, pk):
    post = get_object_or_404(Post, pk=pk)
    return render(request, 'blog/post_view.html', {'post': post})

通过view,请求将会被render到post_view.html这个模板。现在我们创建这个模板(hzblog/templates/blog/post_view.html):

{% extends 'blog/base.html' %}

{% block content %}
    <div class="date">
        {% if post.published_date %}
            {{ post.published_date }}
        {% endif %}
    </div>
    <h1>{{ post.title }}</h1>
    <p>{{ post.text|linebreaks }}</p>
{% endblock %}

这时候,我们访问

http://localhost:8080/post/2/

20161127145736

我们就能够看到文章详情页了。

Django小结

这里可以对创建一个页面/功能的流程进行一个小结。

  1. 在urls.py中添加新页面/功能的路由
  2. 在views.py中添加对应的方法来处理路由发送过来的请求,将数据渲染到对应模板
  3. 在templates文件夹下创建新页面/功能的模板,将views发送过来的数据进行展现

创建文章(post_create)

所谓的创建文章,我们可以理解成向服务器提交一个表单,表单中包含了文章的信息和内容。所以,我们先引入Django的Form来完成我们的功能。首先创建hzblog/forms.py

from django import forms
from .models import Post

class PostForm(forms.ModelForm):

    class Meta:
        model = Post
        fields = ('title', 'text',)

所以接下来,我们按照上面做的小结,开始增加创建文章功能的流程。首先,添加路由

url(r'^post/create/$', views.post_create, name='post_create'),

然后增加views

from django.shortcuts import redirect

def post_create(request):
    if request.method == "POST":
        form = PostForm(request.POST)
        if form.is_valid():
            post = form.save(commit=False)
            post.author = request.user
            post.save()
            return redirect('hzblog:post_view', pk=post.pk)
    else:
        form = PostForm()
    return render(request, 'blog/post_edit.html', {'form': form})

这里使用了一个redirect方法,即创建完文章之后跳转到post_view页面。而在返回中,我们将请求发送到了post_edit模板。这个模板现在还没有创建,因为我们的新增文章和编辑文章都将使用这个模板,所以会在接下来的编辑文章功能部分创建。

最后我们修改模板base.html,在page-header这个div中,增加创建文章按钮:

...
    <div class="page-header">
        <a href="{% url 'hzblog:post_create' %}" class="top-menu"><span class="glyphicon glyphicon-plus"></span></a>
        <h1><a href="/">ZIVER'S</a></h1>
    </div>
...

编辑文章(post_edit)

在创建文章功能中,我们遗留了post_edit这个模板没有添加。在编辑文章功能中,我们将实现这个模板。还是之前的流程,我们先创建路由

url(r'^post/(?P<pk>[0-9]+)/edit/$', views.post_edit, name='post_edit'),

然后增加view方法

def post_edit(request, pk):
    post = get_object_or_404(Post, pk=pk)
    if request.method == "POST":
        form = PostForm(request.POST, instance=post)
        if form.is_valid():
            post = form.save(commit=False)
            post.author = request.user
            post.save()
            return redirect('hzblog:post_view', pk=post.pk)
    else:
        form = PostForm(instance=post)
    return render(request, 'blog/post_edit.html', {'form': form})

最后增加post_edit.html模板

{% extends 'blog/base.html' %}

{% block content %}
    <h1>New post</h1>
    <form method="POST" class="post-form">{% csrf_token %}
        {{ form.as_p }}
        <button type="submit" class="save btn btn-default">Save</button>
    </form>
{% endblock %}

最后,在post_view.html中增加编辑文章的按钮

<a class="btn btn-default" href="{% url 'hzblog:post_edit' pk=post.pk %}"><span class="glyphicon glyphicon-pencil"></span></a>

修改完成后,post_views.html内容如下:

{% extends 'blog/base.html' %}

{% block content %}
    <div class="date">
        {% if post.published_date %}
            {{ post.published_date }}
        {% endif %}
        <a class="btn btn-default" href="{% url 'hzblog:post_edit' pk=post.pk %}"><span class="glyphicon glyphicon-pencil"></span></a>
    </div>
    <h1>{{ post.title }}</h1>
    <p>{{ post.text|linebreaks }}</p>
{% endblock %}

测试

在完成以上功能后,我们可以稍微测试一下效果。因为增加和修改文章都是需要以用户身份执行的,而我们的前端登陆功能还没有实现,所以我们首先用django自带的amin登陆到我们的博客:

http://localhost:8080/admin

然后访问首页

20161127152833

由于没有新文章的发布,首页依然只有一篇文章。右上角有了创建文章的按钮,点击按钮创建文章

20161127152939

这里就有一个可以填写的表单,填写后点击save

20161127153004

保存后,跳转到了文章的详情页。此时的文章还没有发布,所以不会在首页显示,发布后文章右上角将显示发布时间。现在右上角有编辑按钮,点击按钮将回到文章编辑页(和新建文章是同一个模板)。接下来,我们将实现发布功能。

草稿列表(post_drafts)

未发布的文章称为草稿,为了实现发布功能,我们先实现草稿列表页,将未发布的文章列出来。

首先添加路由

url(r'^drafts/$', views.post_drafts, name='post_drafts'),

然后增加view方法

def post_drafts(request):
    posts = Post.objects.filter(published_date__isnull=True).order_by('-created_date')
    return render(request, 'blog/post_drafts.html', {'posts': posts})

之后增加post_drafts.html模板

{% extends 'blog/base.html' %}
{% block content %}
    {% for post in posts %}
        <div class="post">
            <p class="date">created: {{ post.created_date|date:'d-m-Y' }}</p>
            <h1><a href="{% url 'hzblog:post_view' pk=post.pk %}">{{ post.title }}</a></h1>
            <p>{{ post.text|truncatechars:200 }}</p>
        </div>
    {% endfor %}
{% endblock %}

最后在base.html中增加草稿列表页入口按钮

...
    <div class="page-header">
        <a href="{% url 'hzblog:post_create' %}" class="top-menu"><span class="glyphicon glyphicon-plus"></span></a>
        <a href="{% url 'hzblog:post_drafts' %}" class="top-menu"><span class="glyphicon glyphicon-list-alt"></span></a>
        <h1><a href="/">ZIVER'S</a></h1>
    </div>
...

发布文章(post_publish)

增加路由

url(r'^post/(?P<pk>[0-9]+)/publish/$',views.post_publish, name='post_publish'),

增加view方法

def post_publish(request, pk):
    post = get_object_or_404(Post, pk=pk)
    post.publish()
    return redirect('hzblog:post_view', pk=pk)

在post_view页面中增加发布按钮

将下面内容

{% if post.published_date %}
    {{ post.published_date }}
{% endif %}

修改为

{% if post.published_date %}
    {{ post.published_date }}
{% else %}
    <a class="btn btn-default" href="{% url 'blog.views.post_publish' pk=post.pk %}">Publish</a>
{% endif %}

删除文章(post_delete)

增加路由

url(r'^post/(?P<pk>[0-9]+)/delete/$', views.post_delete, name='post_delete'),

增加view方法

def post_delete(request, pk):
    post = get_object_or_404(Post, pk=pk)
    post.delete()
    return redirect('hzblog:index')

在post_view页面中增加发布按钮

 ...  
    <div class="date">
    ...
    {% endif %}
        ...
        <a class="btn btn-default" href="{% url 'hzblog:post_delete' pk=post.pk %}"><span class="glyphicon glyphicon-remove"></span></a>
    </div>
...

至此,博客的基本功能:查看文章,创建文章,编辑文章,删除文章,发布文章功能完成。

Django博客系统开发04

前端改造

在之前的几篇完成后,我们得到了一个简陋的首页,下面我们使用Bootstrap来美化一下我们的前端。

下载Bootstrap

需要下载的是Bootstrap的css和js,以及jquery。这里就不仔细说明了,下载后放到新建的static/目录下即可。现在,整个项目的结构如下:

hzsite
├── hzblog
│   ├── admin.py
│   ├── apps.py
│   ├── __init__.py
│   ├── models.py
│   ├── templates
│   │   └── blog
│   │       └── index.html
│   ├── tests.py
│   ├── urls.py
│   └── views.py
├── hzsite
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── manage.py
└── static
    ├── css
    │   ├── bootstrap.min.css
    │   ├── bootstrap.min.css.map
    │   ├── bootstrap-theme.min.css
    │   ├── bootstrap-theme.min.css.map
    │   └── style.css
    └── js
        ├── bootstrap.min.js
        └── jquery-3.1.1.min.js

注意到这里还有一个style.css,我将在这个文件中定义主体css。

style.css内容如下:

.page-header {
    background-color: #417690;
    margin-top: 0;
    padding: 5px 20px 10px 40px;
}
.page-header h1, .page-header h1 a, .page-header h1 a:visited, .page-header h1 a:active {
    color: #ffffff;
    font-size: 28pt;
    text-decoration: none;
}
.content {
    margin-left: 40px;
}
h1, h2, h3, h4 {
    font-family: 'Microsoft YaHei', cursive;
}
.date {
    float: right;
    color: #828282;
}
.save {
    float: right;
}
.post-form textarea, .post-form input {
    width: 100%;
}
.top-menu, .top-menu:hover, .top-menu:visited {
    color: #ffffff;
    float: right;
    font-size: 26pt;
    margin-right: 20px;
}
.post {
    margin-bottom: 70px;
}
.post h1 a, .post h1 a:visited {
    color: #000000;
}

配置静态目录

下面我们把刚才创建的static目录添加到配置中,修改hzsite/settings.py增加以下内容:

STATICFILES_DIRS = (
    os.path.join(BASE_DIR, "static"),
)

写入到配置后,我们就可以在模板中直接调用static目录下的css和js了。

修改template

修改index.html

{% load staticfiles %}
<html>
<head>
    <title>ZIVER'S</title>
    <script src="{% static 'js/jquery-3.1.1.min.js' %}"></script>
    <link rel="stylesheet" href="{% static 'css/bootstrap.min.css' %}">
    <link rel="stylesheet" href="{% static 'css/bootstrap-theme.min.css' %}">
    <script src="{% static 'js/bootstrap.min.js' %}"></script>
    <link rel="stylesheet" href="{% static 'css/style.css' %}">
</head>
<body>
    <div class="page-header">
        <h1><a href="/">ZIVER'S</a></h1>
    </div>
    <div class="content">
        <div class="row">
            <div class="col-md-8">
                {% for post in posts %}
                    <div class="post">
                        <h1><a href="">{{ post.title }}</a></h1>
                        <p>published: {{ post.published_date }}</p>
                        <p>{{ post.text|linebreaks }}</p>
                    </div>
                {% endfor %}
            </div>
        </div>
    </div>
</body>
</html>

现在,我们的博客首页看起来就舒服多了。

7

模板继承

Django的模板系统支持模板继承,所以我们可以使用继承的方法来减少前端代码的冗余。在index.html的基础上把页面上一般不改变的地方拆分出来创建base.html。内容如下:

<html>
<head>
    <title>ZIVER'S</title>
    <script src="{% static 'js/jquery-3.1.1.min.js' %}"></script>
    <link rel="stylesheet" href="{% static 'css/bootstrap.min.css' %}">
    <link rel="stylesheet" href="{% static 'css/bootstrap-theme.min.css' %}">
    <script src="{% static 'js/bootstrap.min.js' %}"></script>
    <link rel="stylesheet" href="{% static 'css/style.css' %}">
</head>
<body>
    <div class="page-header">
        <h1><a href="/">ZIVER'S</a></h1>
    </div>
    <div class="content">
        <div class="row">
            <div class="col-md-8">
            {% block content %}
            {% endblock %}
            </div>
        </div>
    </div>
</body>
</html>

然后删除掉index.html中的重复内容,并在开头加上模板引用。修改完后的index.html如下:

{% extends 'blog/base.html' %}
{% block content %}
{% for post in posts %}
    <div class="post">
        <h1><a href="">{{ post.title }}</a></h1>
        <p>published: {{ post.published_date }}</p>
        <p>{{ post.text|linebreaks }}</p>
    </div>
{% endfor %}
{% endblock content %}

修改完成后,刷新页面,应该不会有任何变化。

 

Django博客系统开发03

路由Django URL

Django框架通过urls.py文件中的规则对系统进行路由控制。首先我们在主路由hzsite/urls.py中引入hzblog的路由设置:

from django.conf.urls import url
from django.contrib import admin

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'', include('hzblog.urls')),
]

然后,在hzsite/urls.py中设置具体的路由规则

from django.conf.urls import url
from . import views

urlpatterns = [
    url(r'^$', views.index, name='index'),
]

这里我们添加了一条规则,当用户访问网站根目录时,有views中的index方法处理。下面我们去views.py中添加index方法对请求进行处理。

from django.shortcuts import render
from .models import Post

def index(request):
    posts = Post.objects.filter(published_date__isnull=False).order_by('-published_date')
    return render(request, 'blog/index.html', {'posts': posts})

对于路由发来的请求,index函数先调用models查找出符合要求的文章list,然后调用render方法将获取到的数据render到index.html这个模板页面。

最后,我们只需要创建这个index.html模板文件即可。

mkdir -p hzblog/templates/blog
vim hzblog/templates/blog/index.html

模板如下

<html>
<head>
    <title>ZIVER'S</title>
</head>
<body>
    <div>
        <h1><a href="/">ZIVER'S</a></h1>
    </div>
    {% for post in posts %}
    <div>
        <p>published: {{ post.published_date }}</p>
            <h1><a href="">{{ post.title }}</a></h1>
            <p>{{ post.text|linebreaks }}</p>
    </div>
    {% endfor %}
</body>
</html>

这时候,开启服务器,访问我们的主页就能看到如下页面了

6

由于没有加入样式,所以现在的页面比较简陋。这里只显示了Sample 02这篇文章,是因为我们之前在shell中只publish了这一篇,而在index方法中使用过滤器只筛选出了published文章。

Django博客系统开发02

模型Model

Model即MVC模式中的模型,主要是通过ORM与数据库对接,执行对数据库的一些操作。博客系统的所有的模型都将在hzblog/models.py中定义。下面定义我们的第一个Model——Post:

from django.db import models
from django.utils import timezone
from django.contrib.auth.models import User

class Post(models.Model):
    author = models.ForeignKey(User)
    title = models.CharField(max_length=200)
    text = models.TextField()
    created_date = models.DateTimeField(default=timezone.now)
    published_date = models.DateTimeField(blank=True, null=True)

    def publish(self):
        self.published_date = timezone.now()
        self.save()

    def __str__(self):
        return self.title

定义完成后,我们使用migrate命令在数据库中生成相应的表结构

python manage.py makemigrations hzblog
python manage.py migrate hzblog

第一步中,django将为我们创建model修改后需要更改的sql。第二步中将这些更改写入到数据库中。

下面我们在django shell中创建一篇文章

python manage.py shell
>>> from hzblog.models import Post
>>> Post.objects.all()
<QuerySet []>
>>> from django.contrib.auth.models import User
>>> User.objects.create(username='Henry')
<User: Henry>
>>> henry = User.objects.get(username='Henry')
>>> Post.objects.create(author = henry, title = 'Sample 01', text = 'Test')
<Post: Sample 01>
>>> Post.objects.all()
[<Post: Sample 01>]

同样的方法,创建其他Sample文章,现在我们就有了三篇文章

>>> Post.objects.filter(author=user)
[<Post: Sample 01>, <Post: Sample 02>, <Post: Sample 03>]

下面,我们筛选出其中的Sample 02这篇文章并发布

>>> post = Post.objects.get(id=2)
>>> post.publish()
>>> Post.objects.filter(published_date__isnull=False)
[<Post: Sample 02>]

这时候,我们就通过django shell用CLI的方式创建了三篇文章并发布了其中一篇。

后台管理Django Admin

Django框架提供了一个简单的后台管理界面Django Admin。我们先创建一个管理员账号admin:

python manage.py createsuperuser

创建完成后,我们就可以用这个账号登陆Django后台。

http://localhost:8080/admin

2

接下来,我们把我们创建的Post这个Model注册到Django Admin中:

修改hzblog/admin.py

from django.contrib import admin
from .models import Post

admin.site.register(Post)

下面,我们登陆到Django后台,现在已经可以看到我们刚才通过shell创建的几篇文章了。

3

Django后台界面

4

文章列表页

5

文章详情页