Python实战开发之Django (二)

<<< 上一章节,我们已经成功搭建好网站的开发环境

本章节我们开始创建网站

建站第一步

现在我们来做一个简单的备忘笔记网站sthtodo,我们用Django的管理工具django-admin.py创建这个项目

$ django-admin.py startproject sthtodo

创建完成后,我们进入sthtodo项目,并查看sthtodo项目的目录结构

$ cd sthtodo
$ tree

目录显示和说明

(sthtodo) vagrant@precise64:~/sthtodo$ tree
.
|-- manage.py            # 项目最重要的命令行管理工具
`-- sthtodo              # 项目的包sthtodo
    |-- __init__.py      # 包的初始化文件
    |-- settings.py      # 项目的主要配置文件
    |-- urls.py          # 项目的url管理文件
    `-- wsgi.py          # Web服务器的入口

1 directory, 5 files

启动开发服务器,运行项目

$ python manage.py runserver 0.0.0.0:8000

其中IP地址0.0.0.0可以让同网络下的其它设备连接到开发服务器上,8000是端口号,如果IP地址和端口号不声明,程序就默认使用IP地址127.0.0.1和端口号8000,这时命令行显示如下,先忽略You have 13 unapplied migration(s)...这段文字,开发服务器并没有报错,成功启动

(sthtodo) vagrant@precise64:~/sthtodo$ python manage.py runserver 0.0.0.0:8000
Performing system checks...

System check identified no issues (0 silenced).

You have 13 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
Run 'python manage.py migrate' to apply them.

February 16, 2019 - 19:36:46
Django version 1.11.8, using settings 'sthtodo.settings'
Starting development server at http://0.0.0.0:8000/
Quit the server with CONTROL-C.

打开浏览器键入127.0.0.1:8000localhost:8000,显示如下

网站成功运行

这时再留意命令行,多出一行页面请求的信息

Django version 1.11.8, using settings 'sthtodo.settings'
Starting development server at http://0.0.0.0:8000/
Quit the server with CONTROL-C.
[16/Feb/2019 19:42:21] "GET / HTTP/1.1" 200 1716

使用Git管理项目代码

Git是目前最受开发者欢迎和广泛使用的分布式版本控制系统,对于项目本身来说,它可以把项目代码备份到云端,同时储存每一次项目代码的改动,为项目的管理和多人协作提供了便利,接下来简单介绍如何用Git管理你的项目。

安装Git

Windows系统可以在官网的下载页下载安装,安装完成后可以在开始菜单里找到Git => Git Bash (也可以直接点击鼠标右键进入),如果弹出命令行窗口即安装成功,然后就可以用Git的命令行开始项目管理。

Mac OS系统,用Homebrew来安装

$ brew install git

Linux系统,用APT安装

$ sudo apt-get install git

用户信息配置

做为分布式管理系统,每个使用Git的用户设备都建议完善基本信息:用户名和Email邮箱,配置命令如下

$ git config --global user.name "Your Name"
$ git config --global user.email "email@example.com"

创建远程仓库

使用Git管理项目代码,当然少不了在代码托管网站Github上建立远程仓库,首先你需要进入网站注册一个账号。

由于你电脑上安装的Git和Github远程仓库之间的传输是通过SSH加密的,所以我们需要一些配置:

  • 创建SSH Key
    $ ssh-keygen -t rsa -C "your_email@example.com"

首先,你需要把邮箱地址换成你在Github上注册的地址再回车,然后会有路径确认和输入密码的提示,你可以选择忽略,一路回车就行,如果一切顺利的话,用户主目录中将生成.ssh子目录

vagrant@precise64:~$ ssh-keygen -t rsa -C "harry4769@gmail.com"
Generating public/private rsa key pair.
Enter file in which to save the key (/home/vagrant/.ssh/id_rsa): 
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /home/vagrant/.ssh/id_rsa.
Your public key has been saved in /home/vagrant/.ssh/id_rsa.pub.
The key fingerprint is:
......
  • 打开该子目录中的文件id_rsa.pub,复制里面的内容
vagrant@precise64:~$ ls /home/vagrant/.ssh
authorized_keys  id_rsa  id_rsa.pub
vagrant@precise64:~$ vi /home/vagrant/.ssh/id_rsa.pub
  • 回到Github注册好的账户中,进入Account => Settings => SSH and CPG keys,点击New SSH key

  • 接着Title可以随便填,刚才复制的内容粘贴到Key下面,点击Add SSH key,最后你可以看到已经添加好的Key,添加成功

  • 配置完成,接下来就是创建管理项目的仓库Repository,点击右上角的+ (加号),选择New repository,即可创建仓库

推送项目代码

当Github远程仓库成功创建,我们就需要用Git命令把本地的项目代码推送到远程仓库

  • 初始化Git仓库
    $ git init

  • 关联远程仓库
    $ git remote add origin git@github.com:your_name/sthtodo.git

  • 获取远程仓库的更新
    $ git pull origin master

  • 查看项目的改动状态
    $ git status

  • 将所有改动的文件添加到缓存区
    $ git add -A

  • 将缓存区内容添加到本地仓库并提交注释
    $ git commit -m "Start project sthtodo"

  • 最后把本地仓库的内容推送到远程仓库
    $ git push origin master

这时访问Github上的远程仓库,如果显示刚才提交的更新,就推送成功了。

远程仓库克隆

如果我们需要把项目代码转移到其它电脑,或者项目同时需要多人测试开发,最好的方式就是从远程仓库克隆项目代码

$ git clone git@github.com:your_name/sthtodo.git

网站项目的自定义化

Django做为轻量级的Web框架,本身已经架构好Web程序的核心部分,而我们只需要掌握Python的基本语法和程序设计的基础逻辑,就可以进行高效敏捷的开发。

MVC/MTV设计模式

MVC是针对高效的Web开发而广泛运用的设计模式,其中M代表Model(模型,负责连接数据库),V代表View(视图,负责页面的交互),C代表Controller(控制器,负责用户的请求),这三者看似相互独立,却通过简单的配置管理工具紧密结合在一起,构成Web项目的整体。

而对于Django的MTV模式,结合和构成方式与MVC是一致的,只是在定义上有所区别,M依然代表Model(模型,负责连接数据库),T代表Template(模板,负责把页面展示给用户),V代表View(视图,负责后端逻辑,会调用Model和Template)。

除此之外Django框架还包含一个URL分发器,它负责将网址URL的页面请求分发给相应的View处理,View再调用相应的Model和Template,同时你还需要配置Static Files(静态文件),它负责页面的样式布局和前端交互。

综上所述,我们根据这些基本要素,就可以进行自定义化的修改配置,实现动态交互的网站页面。

运用分支管理项目的修改

在项目自定义化修改配置之前,我们用Git在本地仓库新建一个分支config

$ git checkout -b config

这行命令回车之后,本地仓库的新分支config便成功创建,并且直接从master主分支切换到config分支,这时候,我们就可以正式开始项目的修改。

创建新应用(startapp)

现在,我们为sthtodo项目创建两个应用homenote

$ python manage.py startapp home
$ python manage.py startapp note

这时可以看到sthtodo主目录中多出两个文件夹homenote,查看这两个文件夹包含的所有文件

(sthtodo) vagrant@precise64:~/sthtodo$ python manage.py startapp home
(sthtodo) vagrant@precise64:~/sthtodo$ python manage.py startapp note
(sthtodo) vagrant@precise64:~/sthtodo$ ls
README.md   home        note
db.sqlite3  manage.py   sthtodo
(sthtodo) vagrant@precise64:~/sthtodo$ tree home
home
├── __init__.py
├── admin.py
├── apps.py
├── migrations
│   └── __init__.py
├── models.py
├── tests.py
└── views.py

1 directory, 7 files
(sthtodo) vagrant@precise64:~/sthtodo$ tree note
note
├── __init__.py
├── admin.py
├── apps.py
├── migrations
│   └── __init__.py
├── models.py
├── tests.py
└── views.py

1 directory, 7 files

用Git查看改动状态

(sthtodo) vagrant@precise64:~/sthtodo$ git status
On branch config
Untracked files:
  (use "git add <file>..." to include in what will be committed)

    home/
    note/

nothing added to commit but untracked files present (use "git add" to track)

提交修改,并推送到Github远程仓库

(sthtodo) vagrant@precise64:~/sthtodo$ git add -A
(sthtodo) vagrant@precise64:~/sthtodo$ git commit -m "Start app home and note"
[config 6419421] Start app home and note
 14 files changed, 34 insertions(+)
 create mode 100644 home/__init__.py
 create mode 100644 home/admin.py
 create mode 100644 home/apps.py
 create mode 100644 home/migrations/__init__.py
 create mode 100644 home/models.py
 create mode 100644 home/tests.py
 create mode 100644 home/views.py
 create mode 100644 note/__init__.py
 create mode 100644 note/admin.py
 create mode 100644 note/apps.py
 create mode 100644 note/migrations/__init__.py
 create mode 100644 note/models.py
 create mode 100644 note/tests.py
 create mode 100644 note/views.py
(sthtodo) vagrant@precise64:~/sthtodo$ git push origin config
Counting objects: 11, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (10/10), done.
Writing objects: 100% (11/11), 1.03 KiB | 350.00 KiB/s, done.
Total 11 (delta 2), reused 0 (delta 0)
remote: Resolving deltas: 100% (2/2), completed with 1 local object.
remote: 
remote: Create a pull request for 'config' on GitHub by visiting:
remote:      https://github.com/harryhmx/sthtodo/pull/new/config
remote: 
To github.com:harryhmx/sthtodo.git
 * [new branch]      config -> config
进入Github远程仓库,刚才的提交显示在这里,出现了新的分支config,这时点击Compare & pull request进入
标题写上Configuration,下面的Leave a comment可以随便填写或直接跳过,然后点击Create pull request创建新分支config的修改(Pull Request)
新分支config的修改(Pull Request / PR)已成功创建,暂时不要点击Merge pull request(合并分支),先返回到远程仓库
回到远程仓库,这时注意到一个细节,就是Pull requests右边的数字变成了1,现在我们再回到本地仓库的项目中

模板(Template)

Django的MTV模式中,模板(T/Template)的作用是展示给用户交互的页面,通常它是一个html格式的文本,通过浏览器的解析显示文字和图片的页面,在我们创建模板之前,需要一些配置。

配置模板信息

打开子目录sthtodo下的配置文件settings.py

"""
Django settings for sthtodo project.

Generated by 'django-admin startproject' using Django 1.11.8.

For more information on this file, see
https://docs.djangoproject.com/en/1.11/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.11/ref/settings/
"""

import os

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
...

截取该文件代码的开头几行,注意到变量BASE_DIR,它是项目sthtodo主目录的绝对路径,我们往下翻,找到变量TEMPLATES,在DIRS后面的方括号里添加os.path.join(BASE_DIR, 'templates')

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [
                  os.path.join(BASE_DIR, 'templates'),
        ],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

然后,在主目录下创建新的子目录templates,接下来添加的模板文件统一放在该子目录下

$ mkdir templates

添加模板

首先对于网站的模板设计,一般会有一些通用部分,我们先添加第一个通用模板base.html

$ touch templates/base.html

打开通用模板base.html,添加如下代码

<!DOCTYPE html>
<html>

{% include "head.html" %}

<body>
  {% block main_body %}{% endblock %}
</body>

</html>

以上代码中,{% include %}标签表示包含其它模板的内容,也就是接下来创建的第二个通用模板head.html,而名为main_body{% block %}标签则用于接下来创建的继承模板index.htmlnote.html重写替换的部分。

接着,创建第二个通用模板head.html

$ touch templates/head.html

添加代码

<head>
  <meta charset="utf-8"/>
  <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"/>
  <title>{{ head_title|default:'Sthtodo' }}</title>
  <!-- Bootstrap CSS -->
  <link href="http://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
  <!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
  <script src="http://cdn.bootcss.com/jquery/1.12.4/jquery.min.js"></script>
  <!-- Include all compiled plugins (below), or include individual files as needed -->
  <script src="http://cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>

这段代码中,双括号{{}}中的head_title是变量,|是过滤器符号,default是过滤器函数,'Sthtodo'是过滤器函数的参数,整体的含义是在没有声明head_title变量值或者head_title变量值为空值或False0时,默认值为'Sthtodo'

我们所有页面的前端框架引用开源的Bootstrap(3.3.7)和jQuery(1.12.4),Bootstrap的语法可参考getbootstrap官网,jQuery的语法可参考W3school

创建继承模版index.htmlnote.html,然后添加代码

$ touch templates/index.html

{% extends "base.html" %}

{% block main_body %}
  <div class="home-page">
    <div class="container text-center">
      <h1>{{ body_title }}</h1>
      <p><a href="/note/">Go to note</a></p>
    </div>
  </div>
{% endblock %}

$ touch templates/note.html

{% extends "base.html" %}

{% block main_body %}
  <div class="note-page">
    <div class="container text-center">
      <h1>{{ body_title }}</h1>
      <p><a href="/">Back home</a></p>
    </div>
  </div>
{% endblock %}

对于继承模板,使用{% extends %}标签来继承通用模板base.html,然后在名为main_body{% block %}标签下重载不同的内容,最终在继承的通用模板base.html中替换掉同样名为main_body{% block %}标签下的内容。

现在模板的配置和添加完毕,用Git提交修改

(sthtodo) vagrant@precise64:~/sthtodo$ git status
On branch config
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   sthtodo/settings.py

Untracked files:
  (use "git add <file>..." to include in what will be committed)

    templates/

no changes added to commit (use "git add" and/or "git commit -a")
(sthtodo) vagrant@precise64:~/sthtodo$ git add -A
(sthtodo) vagrant@precise64:~/sthtodo$ git commit -m "Create and config templates"
[config 5387939] Create and config templates
 5 files changed, 45 insertions(+), 1 deletion(-)
 create mode 100644 templates/base.html
 create mode 100644 templates/head.html
 create mode 100644 templates/index.html
 create mode 100644 templates/note.html
(sthtodo) Mengxuns-MacBook-Air:sthtodo harry_hmx$ git push origin config
Counting objects: 9, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (9/9), done.
Writing objects: 100% (9/9), 1.21 KiB | 617.00 KiB/s, done.
Total 9 (delta 4), reused 0 (delta 0)
remote: Resolving deltas: 100% (4/4), completed with 3 local objects.
To github.com:harryhmx/sthtodo.git
   6419421..5387939  config -> config

视图和网址(View & URL)

有了模板文件,还要结合视图和网址才能展示页面内容给用户,其中视图的作用是后端逻辑,通过定义视图函数调用相应的模板文件,而网址通过URL配置文件(分发器)关联视图函数,最终通过直接输入网址来展示页面内容。

定义视图函数

打开子目录home下的视图文件views.py,添加代码 (如果没有就创建一个,以下同理)

# -*- coding: utf-8 -*-
from django.shortcuts import render

def index(request):
    print('{}: Request Home Page!'.format(request.get_host()))
    return render(request, 'index.html', {'body_title': 'Home Page'})

在该视图index函数中,我们向服务器输出包含当前主机名和Request Home Page的一段文字,最后的返回值操作调用模板文件index.html并用render()方法渲染模板。

而字典类型的值{'body_title': 'Home Page'}做为参数传递到模板文件index.html,这时模板中的变量{{ body_title }}对应参数值中的'body_title',同时参数值中'body_title'关联值'Home Page',这样模版中的变量{{ body_title }}就被值'Home Page'所覆盖。

接着再打开另一个视图文件note/views.py,添加代码

# -*- coding: utf-8 -*-
from django.shortcuts import render

def index(request):
    print('{}: Request Note Page!'.format(request.get_host()))
    return render(request, 'note.html', {'head_title': 'Sthtodo Note', 'body_title': 'Note Page'})

网址配置

完成视图函数的定义,最后一步就是网址配置。打开子目录sthtodo下的URL配置文件urls.py,首先引入模块如下

from django.conf.urls import url
from django.contrib import admin
from home import views as hv      # New
from note import views as nv      # New

然后在变量urlpatterns中添加如下

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^$', hv.index, name='home'),       # New
    url(r'^note/$', nv.index, name='note'),  # New
]

现在再次启动开发服务器,运行项目

$ python manage.py runserver

打开浏览器,键入网址localhost:8000,页面显示如图
再进入网址localhost:8000/note/,页面显示如图
(sthtodo) vagrant@precise64:~/sthtodo$ python manage.py runserver
Performing system checks...

System check identified no issues (0 silenced).

You have 13 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
Run 'python manage.py migrate' to apply them.

February 18, 2019 - 16:18:52
Django version 1.11.8, using settings 'sthtodo.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
localhost:8000: Request Home Page!
[18/Feb/2019 16:18:57] "GET / HTTP/1.1" 200 855
localhost:8000: Request Note Page!
[18/Feb/2019 16:19:06] "GET /note/ HTTP/1.1" 200 854

这样,一个最简单的自定义网站大功告成。

接下来用Git提交修改,合并config分支

(sthtodo) vagrant@precise64:~/sthtodo$ git status
On branch config
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   home/views.py
    modified:   note/views.py
    modified:   sthtodo/urls.py

no changes added to commit (use "git add" and/or "git commit -a")
(sthtodo) vagrant@precise64:~/sthtodo$ git add -A
(sthtodo) vagrant@precise64:~/sthtodo$ git commit -m "Config views & urls"
[config 9dea3e3] Config views & urls
 3 files changed, 12 insertions(+), 2 deletions(-)
(sthtodo) vagrant@precise64:~/sthtodo$ git push origin config
Counting objects: 8, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (8/8), done.
Writing objects: 100% (8/8), 868 bytes | 868.00 KiB/s, done.
Total 8 (delta 6), reused 0 (delta 0)
remote: Resolving deltas: 100% (6/6), completed with 5 local objects.
To github.com:harryhmx/sthtodo.git
   5387939..9dea3e3  config -> config
打开Github远程仓库,点击进入Pull requests,之后再进入Configuration
点击Merge pull request,之后再点击Confirm merge,合并分支
回到远程仓库,如图所示,已成功合并

最后在本地仓库切换回master主分支,并更新修改

(sthtodo) vagrant@precise64:~/sthtodo$ git checkout master
Switched to branch 'master'
Your branch is up to date with 'origin/master'.
(sthtodo) vagrant@precise64:~/sthtodo$ git pull origin master
Warning: Permanently added the RSA host key for IP address '13.229.188.59' to the list of known hosts.
remote: Enumerating objects: 1, done.
remote: Counting objects: 100% (1/1), done.
remote: Total 1 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (1/1), done.
From github.com:harryhmx/sthtodo
 * branch            master     -> FETCH_HEAD
   74adfd2..c4f8f1f  master     -> origin/master
Updating 74adfd2..c4f8f1f
Fast-forward
 home/__init__.py            |  0
 home/admin.py               |  3 +++
 home/apps.py                |  5 +++++
 home/migrations/__init__.py |  0
 home/models.py              |  3 +++
 home/tests.py               |  3 +++
 home/views.py               |  6 ++++++
 note/__init__.py            |  0
 note/admin.py               |  3 +++
 note/apps.py                |  5 +++++
 note/migrations/__init__.py |  0
 note/models.py              |  3 +++
 note/tests.py               |  3 +++
 note/views.py               |  6 ++++++
 sthtodo/settings.py         |  4 +++-
 sthtodo/urls.py             |  4 ++++
 templates/base.html         | 10 ++++++++++
 templates/head.html         | 12 ++++++++++++
 templates/index.html        | 10 ++++++++++
 templates/note.html         | 10 ++++++++++
 20 files changed, 89 insertions(+), 1 deletion(-)
 create mode 100644 home/__init__.py
 create mode 100644 home/admin.py
 create mode 100644 home/apps.py
 create mode 100644 home/migrations/__init__.py
 create mode 100644 home/models.py
 create mode 100644 home/tests.py
 create mode 100644 home/views.py
 create mode 100644 note/__init__.py
 create mode 100644 note/admin.py
 create mode 100644 note/apps.py
 create mode 100644 note/migrations/__init__.py
 create mode 100644 note/models.py
 create mode 100644 note/tests.py
 create mode 100644 note/views.py
 create mode 100644 templates/base.html
 create mode 100644 templates/head.html
 create mode 100644 templates/index.html
 create mode 100644 templates/note.html

至此,完成了自定义网站最简单最基本的配置。

下一章节,配置静态文件和模型,未完待续 ...

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,029评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,238评论 3 388
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,576评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,214评论 1 287
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,324评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,392评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,416评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,196评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,631评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,919评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,090评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,767评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,410评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,090评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,328评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,952评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,979评论 2 351

推荐阅读更多精彩内容