6. Web應用程序Django2——用戶賬戶1

1. 讓用戶能夠輸入數據

添加幾個頁面,讓用戶能夠輸入數據,能夠添加新主題,添加新條目以及編輯既有條目

只有超級用戶能夠通過管理網站輸入數據,為了不讓用戶與管理網站交互,因此使用Django的表單創建工具來創建讓用戶能夠輸入數據的頁面

  1. 添加新主題

    創建基于表單的頁面方法與創建網頁方法基本一致

    定義一個URL

    編寫一個視圖函數

    編寫一個模版

    基于表單的頁面需要導入包含表單的模塊forms.py

    創建一個名為forms.py的文件,將其存儲到models.py所在的目錄中,并在其中編寫第一個表單
from django import forms

from .models import Topic

class TopicForm(forms.ModelForm):
    class Meta:
        """內嵌Meta類,告訴Django根據那個模型創建表單,這里根據Topic創建一個表單"""
        model = Topic
        #該表單只包含字段text
        fields = ['text']
        #讓Django不要為字段text生成標簽
        labels = {'text':''}


URL模式new_topic(http://localhost:8000/new_topic/),修改learning_logs/urls.py

"""定義learning_logs的URL模式""" 
from django.conf.urls import url 
from . import views

app_name='learning_logs'

urlpatterns = [ 
    # 主頁
    url(r'^$', views.index, name='index'),
    
    # 顯示所有的主題
    url(r'^topics/$', views.topics, name='topics'),

    # 特定主題的詳細頁面
    url(r'^topics/(?P<topic_id>\d+)/$', views.topic, name='topic'),

    #用于添加新主題的網頁
    url(r'^new_topic/$',views.new_topic,name='new_topic'),
    ]

這個URL模式將請求交給視圖函數new_topic()

視圖函數new_topic()

from django.shortcuts import render
from django.http import HttpResponseRedirect
#django.core.urlresolvers在django2.0中合并到django.urls中了
#from django.core.urlresolvers import reverse
from django.urls import reverse

from .models import Topic
from .forms import TopicForm

# Create your views here.

def index(request):
    """學習筆記的主頁"""
    return render(request,'learning_logs/index.html')
    passxxxxx

def topics(request):
    """顯示所有的主題"""
    topics = Topic.objects.order_by('date_added')
    context = {'topics':topics}
    return render(request,'learning_logs/topics.html',context)
    
def topic(request, topic_id):
    """顯示單個主題及其所有的條目"""
    topic = Topic.objects.get(id=topic_id)
    entries = topic.entry_set.order_by('-date_added')
    context = {'topic': topic, 'entries': entries}
    return render(request, 'learning_logs/topic.html', context)

def new_topic(request):
    """添加新主題"""
    if request.method != 'POST':
        #未提交數據:創建一個新表單
        form = TopicForm()
    else:
        #POST提交的數據,對數據進行處理
        form = TopicForm(request.POST)
        if form.is_valid():
            form.save()
            return HttpResponseRedirect(reverse('learning_logs:topics'))
    context = {'form':form}
    return render(request,'learning_logs/new_topic.html',context)

導入了HttpResponseRedirect類,用戶提交主題后將使用這個類將用戶重定向到網 頁topics。函數reverse()根據指定的URL模型確定URL,這意味著Django將在頁面被請求時生成 URL。

函數new_topic()將請求對象作為參數,用戶初次請求網頁時,其瀏覽器將發送GET請求:用戶填寫并提交表單時,其瀏覽器將發送POST請求,根據請求類型,我們可以確定用戶請求的是空表單(GET請求)還是要求對填寫好的表單進行處理(POST請求)

函數is_valid()合適用戶填寫了所有必不可少的字段,且輸入的數據與要求的字段類型一致,如果所有字段都有效,調用save(),將表單中的數據寫入數據庫,保存數據后,可以離開這個頁面了,使用reverse()獲取頁面topics的URL,并將其傳遞給HttpResponseRedirect(),將用戶的瀏覽器重新定向到頁面topics,在頁面topics中,這主題列表中就可以看到剛才輸入的主題

創建模版new_topic.html

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

{% block content %}

  <p>Add a new topic:</p>

  <form action="{% url 'learning_logs:new_topic' %}" method='post'>
    
    {% csrf_token %}
      {{form.as_p}}
      <button name="submit">add topic</button>

  </form>

{% endblock content %}

Django使用模版標簽{% csrf_token %}來防止攻擊者利用表單來獲取對服務器未經授權的訪問(跨站請求偽造)

只需包含模板變量{{ form.as_p }},就可讓Django自動創建顯 示表單所需的全部字段。修飾符as_p讓Django以段落格式渲染所有表單元素,這是一種整潔地顯 示表單的簡單方式。

Django不會為表單創建提交按鈕,因此使用button定義一個這樣的按鈕

鏈接到頁面new_topic

在頁面topics中添加一個到頁面new_topic的鏈接

{% extends "learning_logs/base.html" %} {% block content %}
  <p>Topics</p>
  <ul>
    {% for topic in topics %}
    <li>
      <a href="{% url 'learning_logs:topic' topic.id %}">{{ topic }}</a>
    </li>
    {% empty %}
    <li>No topics have been added yet.</li> 
    {% endfor %}
  </ul>

  <a href="{% url 'learning_logs:new_topic' %}">Add a new topic:</a>

{% endblock content %}
image
  1. 添加新條目

    為了想添加新條目,再次定義URL,編寫視圖函數和模版,并鏈接到添加新條目的網頁

    在forms.py中再添加一個類,創建一個與模型Entry相關聯的表單,這個表單的定制程度比TopicForm要高一些
from django import forms

from .models import Topic,Entry

class TopicForm(forms.ModelForm):
    class Meta:
        """內嵌Meta類,告訴Django根據那個模型創建表單,這里根據Topic創建一個表單"""
        model = Topic
        #該表單只包含字段text
        fields = ['text']
        #讓Django不要為字段text生成標簽
        labels = {'text':''}
        
class EntryForm(forms.ModelForm):
    class Meta:
        model = Entry
        fields = ['text']
        labels = {'text':''}
        widgets = {'text':forms.Textares(attrs={'cols':80})}

屬性widgets,小部件(widget)是一個HTML表單元素,如但行文本框,多行文本區域或下拉列表。通過設置屬性widgets,可覆蓋Django選擇的默認小部件。通過讓 Django使用forms.Textarea,定制字段'text'的輸入小部件,將文本區域的寬度設置為80列,而不是默認的40列。這給用戶提供了足夠的空間,可以編寫有意義的條目。

URL模式new_entry

"""定義learning_logs的URL模式""" 
from django.conf.urls import url 
from . import views

app_name='learning_logs'

urlpatterns = [ 
    # 主頁
    url(r'^$', views.index, name='index'),
    
    # 顯示所有的主題
    url(r'^topics/$', views.topics, name='topics'),

    # 特定主題的詳細頁面
    url(r'^topics/(?P<topic_id>\d+)/$', views.topic, name='topic'),

    #用于添加新主題的網頁
    url(r'^new_topic/$',views.new_topic,name='new_topic'),

    #用于添加新條目的頁面
    url(r'^new_entry/(?P<topic_id>\d+)/$',views.new_entry,name='new_entry')
    ]


視圖函數new_entry()

from django.shortcuts import render
from django.http import HttpResponseRedirect
from django.urls import reverse

from .models import Topic
from .forms import TopicForm,EntryForm

# Create your views here.

def index(request):
    """學習筆記的主頁"""
    return render(request,'learning_logs/index.html')
    passxxxxx

def topics(request):
    """顯示所有的主題"""
    topics = Topic.objects.order_by('date_added')
    context = {'topics':topics}
    return render(request,'learning_logs/topics.html',context)
    
def topic(request, topic_id):
    """顯示單個主題及其所有的條目"""
    topic = Topic.objects.get(id=topic_id)
    entries = topic.entry_set.order_by('-date_added')
    context = {'topic': topic, 'entries': entries}
    return render(request, 'learning_logs/topic.html', context)

def new_topic(request):
    """添加新主題"""
    if request.method != 'POST':
        #未提交數據:創建一個新表單
        form = TopicForm()
    else:
        #POST提交的數據,對數據進行處理
        form = TopicForm(request.POST)
        if form.is_valid():
            form.save()
            return HttpResponseRedirect(reverse('learning_logs:topics'))
    context = {'form':form}
    return render(request,'learning_logs/new_topic.html',context)

def new_entry(request,topic_id):
    """在特定的主題中添加新條目"""
    topic = Topic.objects.get(id=topic_id)

    if request.method != 'POST':
        #未提交數據,創建一個空表單
        form = EntryForm()
    else:
        #POST提交的數據,對數據進行處理
        form = EntryForm(data=request.POST)
        if form.is_valid():
            new_entry = form.save(commit = False)
            new_entry.topic = topic
            new_entry.save()
            return HttpResponseRedirect(reverse('learning_logs:topic',args=[topic_id]))
    context = {'topic':topic,'form':form}
    return render(request,'learning_logs/new_entry.html',context)


模版new_entry.html

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

{% block content %}
  <p><a href="% url 'learning_logs:topic' topic.id %">{{ topic }}</a></p>
  <p>Add a new entry:</p>
  <form action="{% url 'learning_logs:new_entry' topic.id %}" method="post">
    {% csrf_token %}
    {{ form.as_p }}
    <button name="submit">add entry</button>
  </form>
{% endblock content %}


鏈接到頁面new_entry,修改topic.html

{% extends 'learning_logs/base.html' %} 
{% block content %}

  <p>Topic: {{ topic }}</p>
  <p>Entries:</p>
  <p>
    <a href="{% url 'learning_logs:new_entry' topic.id %}">add new entry</a>
  </p>
  <ul>
    {% for entry in entries %} 
    <li>
      <p>{{ entry.date_added|date:'M d, Y H:i' }}</p>
      <p>{{ entry.text|linebreaks }}</p> 
    </li>

  {% empty %}
    <li> 
  There are no entries for this topic yet. 
    </li>
  {% endfor %} 
  </ul>
{% endblock content %}
image
  1. 編輯條目,讓用戶能夠編輯既有條目

    URL模式edit_entry
from django.shortcuts import render
from django.http import HttpResponseRedirect
from django.urls import reverse

from .models import Topic
from .forms import TopicForm,EntryForm

# Create your views here.

def index(request):
    """學習筆記的主頁"""
    return render(request,'learning_logs/index.html')
    passxxxxx

def topics(request):
    """顯示所有的主題"""
    topics = Topic.objects.order_by('date_added')
    context = {'topics':topics}
    return render(request,'learning_logs/topics.html',context)
    
def topic(request, topic_id):
    """顯示單個主題及其所有的條目"""
    topic = Topic.objects.get(id=topic_id)
    entries = topic.entry_set.order_by('-date_added')
    context = {'topic': topic, 'entries': entries}
    return render(request, 'learning_logs/topic.html', context)

def new_topic(request):
    """添加新主題"""
    if request.method != 'POST':
        #未提交數據:創建一個新表單
        form = TopicForm()
    else:
        #POST提交的數據,對數據進行處理
        form = TopicForm(request.POST)
        if form.is_valid():
            form.save()
            return HttpResponseRedirect(reverse('learning_logs:topics'))
    context = {'form':form}
    return render(request,'learning_logs/new_topic.html',context)

def new_entry(request,topic_id):
    """在特定的主題中添加新條目"""
    topic = Topic.objects.get(id=topic_id)

    if request.method != 'POST':
        #未提交數據,創建一個空表單
        form = EntryForm()
    else:
        #POST提交的數據,對數據進行處理
        form = EntryForm(data=request.POST)
        if form.is_valid():
            new_entry = form.save(commit = False)
            new_entry.topic = topic
            new_entry.save()
            return HttpResponseRedirect(reverse('learning_logs:topic',args=[topic_id]))
    context = {'topic':topic,'form':form}
    return render(request,'learning_logs/new_entry.html',context)


def edit_entry(request,entry_id):
    """編輯既有條目"""
    entry = Entry.objects.get(id = entry_id)
    topic = entry.topic

    if request.method != 'POST':
        #初次請求,使用當前條目填充表單
        form = EntryForm(instance=entry)
    else:
        #POST提交的數據,對數據進行處理
        form = EntryForm(instance=entry,data=request.POST)
        if form.is_valid:
            form.save()
            return HttpResponseRedirect(reverse('learning_logs:topic',args=[topic.id]))
    context = {'entry':entry,'topic':topic,'form':form}
    return render(request,'learning_logs/edit_entry.html',context)


模版edit_entry

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

{% block content %}

  <p><a href="{% url 'learning_logs:topic' topic.id %}">{{ topic }}</a></p>
  <p>Edit entry:</p>
  <form action="{% url 'learning_logs:edit_entry' entry.id %}" method='post'>
    {% csrf_token %}
    {{ form.as_p}}
    <button name="submit">save changes</button>
  </form>

{% endblock content %}


鏈接到頁面edit_entry

{% extends 'learning_logs/base.html' %} 
{% block content %}

  <p>Topic: {{ topic }}</p>
  <p>Entries:</p>
  <p>
    <a href="{% url 'learning_logs:new_entry' topic.id %}">add new entry</a>
  </p>
  <ul>
    {% for entry in entries %} 
    <li>
        <p>{{ entry.date_added|date:'M d, Y H:i' }}</p>
      <p>{{ entry.text|linebreaks }}</p> 
      <p>
        <a href="{% url 'learning_logs:edit_entry' entry.id %}">edit entry</a>
      </p>
    </li>

  {% empty %}
    <li> 
  There are no entries for this topic yet. 
    </li>
  {% endfor %} 
  </ul>
{% endblock content %}
image

2. 創建用戶賬戶

建立一個用戶注冊和身份驗證系統,讓用戶能夠注冊賬戶,進而登錄和注銷,將創建一個新的應用程序,包含與處理賬戶相關的所有功能,對模型Topic稍做修改,讓每個主題都歸屬于特定用戶

  1. 使用命令startapp來創建一個名為users的應用程序
(ll_env) yangdongxingdeMacBook-Pro:learning_log yangdongxing$ python3 manage.py startapp users
(ll_env) yangdongxingdeMacBook-Pro:learning_log yangdongxing$ ls
db.sqlite3  learning_logs   manage.py
learning_log    ll_env      users
(ll_env) yangdongxingdeMacBook-Pro:learning_log yangdongxing$ ls users
__init__.py apps.py     models.py   views.py
admin.py    migrations  tests.py
(ll_env) yangdongxingdeMacBook-Pro:learning_log yangdongxing$ 


將users添加到settings.py中

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    #我的應用程序
    'learning_logs',
    'users',
]


修改項目根目錄的urls.py,其中包含我們將應用程序users定義的URL

from django.contrib import admin
from django.urls import path,include


urlpatterns = [
    path('admin/', admin.site.urls),
    path('users/',include('users.urls',namespace='users')),
    path('', include('learning_logs.urls', namespace='learning_logs')),
]

添加了一行代碼,以包含應用程序users中的文件urls.py。這行代碼與任何以單詞users 打頭的URL(如http://localhost:8000/users/login/)都匹配。還創建了命名空間'users',以便將應用程序learning_logs的URL同應用程序users的URL區分開來

登錄界面,在learning_log/users/中新建urls.py的文件夾

"""為應用程序users定義URL模式"""

from django.conf.urls import url
#導入默認是圖login
from django.contrib.auth.views import login
from . import views

urlpatterns = [
    #登錄界面
    url(r'^login/$',login,{'template_name':'users/login.html'},name='login'),
]

在learning_log/users/中,創建目錄templates,在里面創建目錄users,建立登錄模版login.html

{% extends "learning_logs/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 'users:login' %}">
  {% csrf_token %}
  {{ form.as_p }}

  <button name="submit">log in</button>
  <input type="hidden" name="next" value="{% url 'learning_logs:index' %}"></input>
  </form>
{% endblock content %}

注:一個應用程序中的模版可繼承另一個應用程序的模版

在base.htmlz紅添加到登錄頁面的鏈接,讓所有頁面都包含它

<p>
    <a href="{% url 'learning_logs:index' %}">Learning Log</a>
    <a href="{% url 'learning_logs:topics' %}">Topics</a>
    {% if user.is_authenticated %}
      Hello,{{user.username}}
    {% else %}
      <a href="{% url 'users:login' %}">log in</a>
    {% endif %}
</p>>

{% block content %}{% endblock content %}

在Django身份驗證系統中,每個人模版都可使用user,這個變量有一個is_authenticated屬性:如果用戶已登錄,該屬性為True,否則為false,可以使用這個屬性向已通過身份驗證的用戶顯示一條信息,而未通過身份驗證的用戶顯示另一條消息

  1. 使用登錄頁面

    訪問地址http://localhost:8000/admin/,如果依然使用的是管理員身份登錄的,右上角退出當前賬戶

    訪問時會報錯TemplateDoesNotExist at /users/login/

[圖片上傳失敗...(image-e34764-1526949597206)]
解決辦法,在settings中添加DIRS即可

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',
            ],
        },
    },
]
image
  1. 注銷

    注銷URL,修改users/urls.py
"""為應用程序users定義URL模式"""

from django.conf.urls import url
#導入默認是圖login
from django.contrib.auth.views import login
from . import views

app_name='users'

urlpatterns = [
    #登錄界面
    url(r'^login/$',login,{'template_name':'users/login.html'},name='login'),
    #注銷
    url(r'logout/$',views.logout_view,name='logout'),
]

視圖函數logout_view(),修改users/views.py

from django.shortcuts import render
from django.http import HttpResponseRedirect
from django.contrib.auth import logout

# Create your views here.
def logout_view(request):
    """注銷用戶"""
    logout(request)
    return HttpResponseRedirect(reverse('learning_logs:index'))
    pass

從django.contrib.auth中導入了函數logout(),將request對象作為參數,然后重新定向到主頁

鏈接到注銷視圖,在base.html中添加這種鏈接,讓每個頁面都包含它,將其放在標簽{% if user.is_authenticated %}中,使得僅當用戶登錄后才看到它

<p>
    <a href="{% url 'learning_logs:index' %}">Learning Log</a>
    <a href="{% url 'learning_logs:topics' %}">Topics</a>
    {% if user.is_authenticated %}
      Hello,{{user.username}}
      <a href="{% url 'users:logout' %}">logout out</a>
    {% else %}
      <a href="{% url 'users:login' %}">log in</a>
    {% endif %}
</p>>

{% block content %}{% endblock content %}
  1. 注冊頁面,使用Django提供的表單UserCreationForm編寫視圖函數和模板

    注冊頁面的URL模式

    視圖函數register(),在注冊頁面首次被請求時,視圖函數register()需要顯示一個空的注冊表單,并在用戶提交填寫好的注冊表單時對其進行處理,如果注冊成功,這個函數還需要讓用戶自動登錄,在users/views.py中添加視圖
from django.shortcuts import render
from django.http import HttpResponseRedirect
from django.urls import reverse
from django.contrib.auth import logout,login,authenticate
from django.contrib.auth.forms import UserCreationForm

# Create your views here.
def logout_view(request):
    """注銷用戶"""
    logout(request)
    return HttpResponseRedirect(reverse('learning_logs:index'))
    


def register(request):
    """注冊新用戶"""
    if request.method != 'POST':
        #顯示空的注冊表單
        form = UserCreationForm()
    else:
        #處理填寫好的表單
        form = UserCreationForm(data=request.POST)

        if form.is_valid:
            new_user = form.save()
            # 讓用戶自動登錄,再重定向到主頁
            authenticated_user = authenticate(username=new_user.username,password=request.POST['password1'])
            login(request,authenticated_user)
            return HttpResponseRedirect(reverse('learning_logs:index'))
    context = {'form':form}
    return render(request,'users/register.html',context)

默認表單 UserCreationForm,在上面檢查是否是POST請求,如果不是,創建UserCreationForm實例,使用form.is_valid判斷輸入的數據是否有效,如果有效調用表單的放大save(),將用戶名和密碼的散列值保存到數據庫中,save()返回新創建的用戶對象,我們將其存儲在new_user中

讓用戶自動登錄,調用authenticate(),并將實參new_user.username和密碼傳遞給它,用戶注冊時,輸入了倆次密碼,倆次密碼相同,所以使用password和password1是一樣的,如果用戶名和密碼是正確的,方法authenticate()將返回一個通過了身份驗證的用戶對象,調用函數login(),并將對象request和authenticated_user傳遞給它,為新用戶創建有效的會話,將用戶重定向到主頁

注冊模版,在login.html所在的目錄中新建register.html

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

{% block content %}

    <form method="post" action="{% url 'users:register' %}">
        {% block content %}
        {{ form.as_p }}

        <button name="submit">register</button>
        <input type="hidden" name="next" value="{% url 'learning_logs:index' %}"/>
    </form>         
 
{% endblock content %}

方法as_P,讓Django在表單中正確地顯示所有字段,包括錯誤信息

鏈接到注冊頁面
修改base.html將注冊鏈接放在頁面頂部

<p>
    <a href="{% url 'learning_logs:index' %}">Learning Log</a>
    <a href="{% url 'learning_logs:topics' %}">Topics</a>
    {% if user.is_authenticated %}
      Hello,{{user.username}}
      <a href="{% url 'users:logout' %}">logout out</a>
    {% else %}
      <a href="{% url 'users:register' %}">register</a>
      <a href="{% url 'users:login' %}">log in</a>
    {% endif %}
</p>>

{% block content %}{% endblock content %}
image

注冊時報錯The User could not be created because the data didn't validate.

原因時在register.py中form驗證出錯,form.is_valid()補全即可,注冊完后的樣式
image
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,119評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,382評論 3 415
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,038評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,853評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,616評論 6 408
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,112評論 1 323
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,192評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,355評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,869評論 1 334
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,727評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,928評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,467評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,165評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,570評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,813評論 1 282
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,585評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,892評論 2 372

推薦閱讀更多精彩內容