Django圖書薦購云平臺開發(fā)與實(shí)踐 - 3用戶信息模塊

接下來開發(fā)用戶信息模塊疙挺,用戶信息模塊主要包括用戶注冊、用戶登錄怜浅、顯示用戶信息铐然、用戶密碼的修改。
用戶的注冊恶座、登陸搀暑、密碼修改和找回功能在前面已經(jīng)實(shí)現(xiàn),只需要略做修改就可以了跨琳。參見(10) Django - Auth認(rèn)證系統(tǒng)
由于用戶信息表需要和圖書館信息表關(guān)聯(lián)自点,這里一并要把圖書館信息表的模型給實(shí)現(xiàn)了。

# user 的 models.py 
from django.db import models
from django.contrib.auth.models import AbstractUser

class Library(models.Model):
    lib_id = models.AutoField('序號', primary_key=True)
    lib_name = models.CharField('圖書館名稱', max_length=50)
    lib_address = models.CharField('地址', max_length=150)
    lib_contact = models.CharField('聯(lián)系人', max_length=20)
    lib_phone = models.CharField('聯(lián)系電話', max_length=20)
    lib_email = models.EmailField('Email', max_length=150)

    def __str__(self):
        return self.lib_name

    class Meta:
        verbose_name = '圖書館用戶'
        verbose_name_plural = '圖書館用戶'

class MyUser(AbstractUser):
    id_number = models.CharField('學(xué)號/工號', max_length=16)
    avatar = models.ImageField(upload_to='avatar', default='default.png', verbose_name="頭像")
    qq = models.CharField('QQ號碼', max_length=16)
    weChat = models.CharField('微信賬號', max_length=100)
    mobile = models.CharField('手機(jī)號碼', max_length=11)
    lib_id = models.ForeignKey(Library, on_delete=models.CASCADE, blank=True, null=True, verbose_name='所屬館')
    # 設(shè)置返回值
    def __str__(self):
        return self.username

    class Meta:
        verbose_name = '個(gè)人用戶'
        verbose_name_plural = '個(gè)人用戶'

定義好模型后脉让,需要?jiǎng)h除之前的全部數(shù)據(jù)表和所有app下migrations文件下的0001_initial.py文件桂敛,刪除之前將表中數(shù)據(jù)導(dǎo)出保存好,最后重新執(zhí)行makegirations和migrate命令創(chuàng)建好模型和數(shù)據(jù)庫表溅潜。接著需要重寫user下的__init__.py文件术唬,以在后臺顯示修改后的MyUser模型。

#user 的 __init__.py
#設(shè)置App(user)的中文名
from django.apps import AppConfig
import os
# 修改app在admin后臺顯示名稱
# default_app_config的值來自apps.py的類名
default_app_config = 'user.IndexConfig'

# 獲取當(dāng)前app的命名
def get_current_app_name(_file):
    return os.path.split(os.path.dirname(_file))[-1]

# 重寫類IndexConfig
class IndexConfig(AppConfig):
    name = get_current_app_name(__file__)
    verbose_name = '用戶管理'

最后在user的admin.py中注冊新的模型即可滚澜。

#user 的 admin.py
from django.contrib import admin
from .models import MyUser, Library
from django.contrib.auth.admin import UserAdmin
from django.utils.translation import gettext_lazy as gl

@admin.register(MyUser)
class MyUserAdmin(UserAdmin):
    list_display = ['username', 'email', 'id_number', 'mobile', 'qq', 'weChat', 'lib_id']
    #修改用戶時(shí)粗仓,在個(gè)人信息里添加 'id_number'、'mobile 博秫、'qq'潦牛、'weChat'的信息錄入
    #將源碼的UserAdmin.fieldsets轉(zhuǎn)換成列表格式
    fieldsets = list(UserAdmin.fieldsets)
    #重寫UserAdmin的fieldsets,添加'id_number'挡育、'mobile'巴碗、'qq'、'weChat'的信息錄入
    fieldsets[1] = (gl('Personal info'), {'fields':('first_name','last_name','email','id_number','mobile','qq','weChat','lib_id')})

@admin.register(Library)
class LibraryAdmin(admin.ModelAdmin):
    #設(shè)置顯示的字段
    list_display = ['lib_id','lib_name', 'lib_address', 'lib_contact', 'lib_phone', 'lib_email']
    #設(shè)置搜索字段
    search_fields = ['lib_id', 'lib_name']
    #設(shè)置每頁最大記錄數(shù)
    list_per_page = 20
    #設(shè)置顯示字段中可被鏈接的字段
    list_display_links = ['lib_id', 'lib_name']
    #設(shè)置在列表展示頁面可更改的字段
    # list_editable = ['cata_id']

準(zhǔn)備工作就緒以后即寒,打開admin后臺管理橡淆,在這之前不要忘記創(chuàng)建superuser∧刚裕可以看到后臺用戶管理模塊里多里一個(gè)圖書館模塊逸爵。點(diǎn)擊增加圖書館,可以添加圖書館信息凹嘲,這里添加了2個(gè)圖書館师倔。


image.png

在個(gè)人用戶修改信息的界面,可以看到有一個(gè)所屬館的下拉框周蹭,可以為個(gè)人用戶添加所屬館的信息趋艘。


image.png

到這里疲恢,用戶信息模塊的準(zhǔn)備工作就做的差不多了,下面開始逐一實(shí)現(xiàn)用戶信息模塊的其他功能瓷胧。

會(huì)話控制

在實(shí)際使用中显拳,還需要會(huì)話控制session。在驗(yàn)證登陸時(shí)搓萧,將用戶名保存到session中杂数,然后在base.html模板中做一個(gè)驗(yàn)證,判斷用戶是或否登陸瘸洛,已經(jīng)登陸則顯示用戶名和退出按鈕揍移,沒有登陸的顯示登陸按鈕。

#base.html 的 網(wǎng)頁頭
      <!--網(wǎng)頁頭-->
      <div class="container clearfix">
          <div class="float-left">
              <img src="{% static 'images/logo.png' %}" >
          </div>
          <div class="float-right">
              {# 如果session中沒有用戶username货矮,則顯示登陸 #}
              {% if not request.session.username %}
              <a href="{% url 'login' %}"><button class="btn btn-success">登陸</button></a>
              {% else %}
              <a href="#"><button type="button" class="btn btn-outline-success">
                    {{ request.session.username }}
              </button></a>
              <a href="{% url 'logout' %}"><button type="button" class="btn btn-outline-success">退出</button></a>
              {% endif %}
            </div>
      </div>
#user 的views.py
def loginView(request):
    #設(shè)置標(biāo)題和兩外兩個(gè)URL鏈接
    title = '登錄'
    headers = '用戶登錄'
    unit_2 = '/user/register.html'
    unit_2_name = '立即注冊'
    unit_1 = '/user/setpassword.html'
    unit_1_name = '修改密碼'

    if request.method == 'POST':
        #用戶提交登錄羊精,獲取登錄的用戶名和密碼
        username = request.POST.get('username', '')
        password = request.POST.get('password', '')
        #首先查找User數(shù)據(jù)表中有沒有該用戶,沒有提示注冊
        if MyUser.objects.filter(username=username):
            #如果有該用戶囚玫,則檢查用戶名和密碼是否正確,錯(cuò)誤提示重新輸入
            user = authenticate(username=username, password=password)
            if user:
                if user.is_active:##判斷用戶是否被激活读规,是則由內(nèi)置函數(shù)login完成登錄抓督,跳轉(zhuǎn)到主頁
                    login(request, user)
                    #將用戶的工號/學(xué)號寫入session
                    request.session['username'] = user.username
                    return redirect('/book')
            else:
                tips = '賬號密碼錯(cuò)誤,請重新輸入'
        else:
            tips = '用戶不存在束亏,請注冊'
    return render(request, 'user.html', locals())

def logoutView(request):
    logout(request)#退出登錄
    try:
        del request.session['userid']
    except KeyError:
        pass
    return redirect('/user/login.html')#跳轉(zhuǎn)到登錄頁面

代碼和前面章節(jié)的基本相同铃在,除了在登陸成功時(shí)將用戶名寫入session,以及在模板中對用戶名做一個(gè)檢查碍遍,最后在登出時(shí)刪除session定铜。

用戶個(gè)人信息展示

這里將要實(shí)現(xiàn)一個(gè)個(gè)人信息展示頁,其中展示了個(gè)人全部的信息怕敬,并且允許個(gè)人用戶可以修改部分個(gè)人信息揣炕,如密碼、聯(lián)系方式等东跪。有些信息不能修改畸陡,有些可以修改。個(gè)人信息展示比較簡單虽填,只要通過session做一個(gè)判斷丁恭,如果用戶登錄,則從數(shù)據(jù)庫獲取用戶的個(gè)人信息并展示給用戶斋日,如果session里沒有用戶登錄信息牲览,則跳轉(zhuǎn)到登錄頁面。
下面是代碼:

#定義URL
    path('userinfo.html', views.userinfoView, name='userinfo'),
#userinfo.html模板
{% extends 'base.html' %}
{% load staticfiles %}
<link rel="stylesheet" >
<link rel="stylesheet" href="{% static 'css/mycss.css' %}">
{% block search %}
{% endblock %}
{% block body %}
<div class="container" style="margin-top:30px">
    <div class="row">
       <div class="col-sm-4">
           <div class="fakeimg border">
               <img class="img-fluid img-responsive" src="#" alt='頭像'>
           </div>
           <hr class="d-sm-none">
       </div>
       <div class="col-sm-8">
           <h5 class="font-weight-bold">個(gè)人信息</h5>
           <form class="mx-auto" action="" method="POST">
            {% csrf_token %}
           <div class="form-group">
            <label for="usr">用戶名</label>
            <input type="text" class="form-control" id="usr" placeholder="{{ user.username }}">
          </div>
          <div class="form-inline">
                <label for="first_name">姓</label>
                <input type="text" class="form-control" id="first_name" value="{{ user.first_name }}" disabled>
                <label for="last_name">名</label>
                <input type="text" class="form-control" id="last_name" value="{{ user.last_name }}" disabled>
                </div>
          <div class="form-group">
            <label for="id_number">工號/學(xué)號</label>
            <input type="text" class="form-control" id="id_number" placeholder="{{ user.id_number }}" disabled>
          </div>
          <div class="form-group">
                <label for="email">Email</label>
                <input type="text" class="form-control" id="email" value="{{ user.email }}">
         </div>
         <div class="form-group">
                <label for="qq">QQ</label>
                <input type="text" class="form-control" id="qq" value="{{ user.qq }}">
         </div>
         <div class="form-group">
                <label for="wechat">微信</label>
                <input type="text" class="form-control" id="wechat" value="{{ user.weChat }}">
         </div>
         <div class="form-group">
                <label for="mobile">手機(jī)</label>
                <input type="text" class="form-control" id="mobile" value="{{ user.mobile }}">
         </div>
         <div class="form-group">
                <label for="lib">所屬館</label>
                <input type="text" class="form-control" id="lib" value="{{ user.lib_id }}" disabled>
         </div>
         <div class="input-group mb-3 ">
                <button type="submit" class="btn btn-primary btn-block">保存</button>
            </div>
         </form>
           <div class="fakeimg">薦購歷史</div>
           </div>
         </div>
       </div>
{% endblock %}
#user 的 views.py 的 userinfoView
def userinfoView(request):
    if not request.session.get('username'):
        return redirect('login.html')
    else:
        username = request.session.get('username')
        user = MyUser.objects.filter(username=username)[0]
        return render(request, 'userinfo.html', locals())

初步的個(gè)人信息頁面展示如下:

image.png

可以看到左邊這里有個(gè)頭像框的預(yù)留位置恶守,下面就要實(shí)現(xiàn)用戶上傳和修改頭像的功能第献。

用戶頭像的上傳與更改

要實(shí)現(xiàn)用戶頭像的上傳首先需要做一些準(zhǔn)備工作跛蛋。
首先我們在重寫user模型的時(shí)候,里面要添加一個(gè)字段痊硕,用來保存用戶上傳圖片的地址信息赊级。

avatar = models.ImageField(upload_to='avatar', default='default.png', verbose_name="頭像")

上面MyUser模型完整的代碼里已經(jīng)包含了avatar這個(gè)字段,其中的參數(shù)upload_to表示圖片上傳到哪里岔绸,default參數(shù)可選理逊,表示默認(rèn)的圖片,如果沒有default參數(shù)盒揉,那必須加上null=True,blank=True參數(shù)晋被,否則在執(zhí)行數(shù)據(jù)遷移時(shí)會(huì)報(bào)錯(cuò)。


模型中定義好字段以后刚盈,我們還需要在項(xiàng)目的settings.py中設(shè)置用戶上傳圖片的目錄和路徑羡洛。

#settings.py
#用戶上傳圖片的路徑, 'user'是app應(yīng)用名藕漱,表示圖片上傳到user/media/avatar下
MEDIA_ROOT = os.path.join(BASE_DIR, 'user', "media/avatar")
#MEDIA_URL是用戶從前臺讀取圖片的地址欲侮,最后的'/'不能省
MEDIA_URL = "media/avatar/"

接下來我們在user應(yīng)用下新建一個(gè)forms.py,用來定義表單模型肋联。

from django import forms

#上傳頭像圖片的表單
class AvataruploadForm(forms.Form):
    avatar = forms.ImageField()

然后到應(yīng)用的urls.py里添加URL地址信息,userinfo用來展示用戶信息和修改用戶頭像威蕉,alteruserinfo用來修改用戶信息。

    path('userinfo.html', views.userinfoView, name='userinfo'),
    path('alteruserinfo.html', views.alterUserinfoView, name='alteruserinfo'),

接下來分別編寫視圖函數(shù)橄仍。

#展示個(gè)人信息頁和修改頭像,@login_required驗(yàn)證登錄韧涨,未登錄則跳轉(zhuǎn)到登錄頁面
@login_required
def userinfoView(request):
    #獲取用戶名
    username= request.user.username
    #獲取該用戶的模型實(shí)例對象
    user = get_object_or_404(MyUser, username=username)
    #如果是POST請求,則說明用戶是在修改頭像
    if request.method == 'POST':
        #將用戶的請求信息和上傳的圖片文件放入自定義的表單模型中
        form = AvataruploadForm(request.POST, request.FILES)
        #驗(yàn)證表單
        if form.is_valid():
            #獲取用戶上傳的文件
            avatar = request.FILES['avatar']
            #設(shè)置保存的文件名
            imagename = get_random_str() + '.jpg'
            #保存文件的路徑
            imagepath = os.path.join(settings.MEDIA_ROOT, imagename)
            #使用pillow壓縮和保存圖像文件
            img = Image.open(avatar)
            crop_im = img.resize((300, 300), Image.ANTIALIAS)
            crop_im.save(imagepath)
        
            try:
                #如果存在老的頭像且不是默認(rèn)頭像就刪除
                if request.user.avatar != 'default.png':
                    oldimage = '%s/%s' % (settings.MEDIA_ROOT, request.user.avatar)
                    os.remove(oldimage)
            except:
                pass
                
            #更新用戶的頭像在數(shù)據(jù)庫中的地址
            user.avatar = imagename
            user.save()
            #跳轉(zhuǎn)到用戶信息頁
            return redirect('userinfo.html')
    return render(request, 'userinfo.html', locals()) 

上面的展示用戶信息和修改用戶頭像侮繁,每一步都說明的很清楚虑粥,接下來,實(shí)現(xiàn)修改用戶信息宪哩。

修改用戶信息

首先在forms.py中定義個(gè)人信息的數(shù)據(jù)模型表單及驗(yàn)證函數(shù).

from django import forms
from .models import MyUser, Library
import re
#個(gè)人信息的數(shù)據(jù)庫表單
class UserinfoForm(forms.ModelForm):
    #模型與表單設(shè)置
    class Meta:
        #綁定模型
        model = MyUser

        #選擇轉(zhuǎn)換哪些模型的字段為表單字段
        fields = ['first_name','last_name','id_number','email', 'qq','weChat','mobile','lib_id']
        #定義表單字段的css樣式
        widgets = {
            'first_name': forms.widgets.TextInput(attrs={'class': 'form-control','autocomplete':'off'}),
            'last_name': forms.widgets.TextInput(attrs={'class': 'form-control','autocomplete':'off'}),
            'id_number': forms.widgets.TextInput(attrs={'class': 'form-control','autocomplete':'off'}),
            'email': forms.widgets.EmailInput(attrs={'class': 'form-control','autocomplete':'off'}),
            'qq': forms.widgets.TextInput(attrs={'class': 'form-control','autocomplete':'off'}),
            'weChat': forms.widgets.TextInput(attrs={'class': 'form-control','autocomplete':'off'}),
            'mobile': forms.widgets.TextInput(attrs={'class': 'form-control','autocomplete':'off'}),
           
        }

    # 函數(shù)必須以clean_開頭娩贷,以模型的字段名結(jié)尾,如mobile是MyUser模型的字段
    def clean_mobile(self):  
        """
        通過正則表達(dá)式驗(yàn)證手機(jī)號碼是否合法
        """
        mobile = self.cleaned_data['mobile']
        mobile_regex = r'^1[34578]\d{9}$'
        p = re.compile(mobile_regex)
        if p.match(mobile):
            return mobile
        else:
            raise forms.ValidationError('手機(jī)號碼非法', code='invalid mobile')

    def clean_qq(self):
        qq = self.cleaned_data['qq']
        if qq.isdigit():
            return qq
        else:
            raise forms.ValidationError('QQ號碼應(yīng)全部為數(shù)字',  code='invalid qq')

    def clean_id_number(self):
        id_number = self.cleaned_data['id_number']
        if id_number.isdigit():
            return id_number
        else:
            raise forms.ValidationError('學(xué)號/工號應(yīng)全部為數(shù)字',  code='invalid id_number')


繼續(xù)編寫修改個(gè)人信息的視圖函數(shù)斋射。

#修改個(gè)人信息,@login_required驗(yàn)證登錄育勺,未登錄則跳轉(zhuǎn)到登錄頁面
@login_required(login_url='/user/login.html')
def alterUserinfoView(request):
    #獲取用戶名
    username = request.user.username
    #獲取該用戶的實(shí)例化模型對象
    instance = MyUser.objects.get(username=username)
    if instance:
        #將實(shí)例化模型賦給自定義的表單模型
        user = UserinfoForm(instance=instance)
    #如果是POST請求,則說明用戶想修改個(gè)人信息
    if request.method == 'POST':
        #將用戶的POST請求信息和用戶的實(shí)例化模型放入自定義表單中
        userinfo = UserinfoForm(request.POST, instance=instance)
        #驗(yàn)證表單,通過則保存表單數(shù)據(jù)
        if userinfo.is_valid():
            userinfo.save()
            #跳轉(zhuǎn)到用戶信息展示頁
            return redirect('userinfo.html')
        else:
            #未通過驗(yàn)證罗岖,向用戶展示錯(cuò)誤消息
            error_msg = userinfo.errors.as_json()
  
    return render(request, 'alteruserinfo.html', locals())

到這里涧至,用戶信息模塊基本上就實(shí)現(xiàn)的差不多了。
由于薦購系統(tǒng)需要實(shí)名制桑包,因此在讀者修改個(gè)人資料以后需要圖書館管理員進(jìn)行后臺認(rèn)證南蓬,認(rèn)證通過的讀者才能進(jìn)行薦購,而且不能再修改姓名、學(xué)號/工號和所屬館的資料赘方。
權(quán)限的驗(yàn)證主要通過模板進(jìn)行烧颖,如將讀者分為普通讀者和認(rèn)證讀者,認(rèn)證讀者有薦購權(quán)限窄陡,那么在模板中可以這樣設(shè)置:

{# 對讀者權(quán)限進(jìn)行驗(yàn)證炕淮,如果有薦購權(quán)限,說明讀者資料通過審核跳夭,不允許再修改姓名涂圆、工號和所屬館 #}
{% if perms.recommend.add_recommend %}
    <fieldset disabled >
{% else %}
    <fieldset>
{% endif %}
<div class="form-group">
      <label class="badge badge-secondary" for="name" >姓</label>
      {{ user.last_name }} 
</div>
<div class="form-group">
      <label class="badge badge-secondary" for="name" >名</label>
      {{ user.first_name }} 
</div>
...
</fieldset>

fieldset是bootstrap4中的禁用字段集,對 <fieldset> 添加 disabled 屬性來禁用 <fieldset> 內(nèi)的所有控件币叹。

到這里润歉,我們實(shí)現(xiàn)了用戶的注冊、登陸颈抚、修改密碼踩衩、密碼找回,還實(shí)現(xiàn)了用戶的個(gè)人信息中心贩汉,用戶可以修改頭像以及部分個(gè)人信息驱富。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市雾鬼,隨后出現(xiàn)的幾起案子萌朱,更是在濱河造成了極大的恐慌,老刑警劉巖策菜,帶你破解...
    沈念sama閱讀 221,548評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異酒贬,居然都是意外死亡又憨,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,497評論 3 399
  • 文/潘曉璐 我一進(jìn)店門锭吨,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蠢莺,“玉大人,你說我怎么就攤上這事零如□锝” “怎么了?”我有些...
    開封第一講書人閱讀 167,990評論 0 360
  • 文/不壞的土叔 我叫張陵考蕾,是天一觀的道長祸憋。 經(jīng)常有香客問我,道長肖卧,這世上最難降的妖魔是什么蚯窥? 我笑而不...
    開封第一講書人閱讀 59,618評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上拦赠,老公的妹妹穿的比我還像新娘巍沙。我一直安慰自己,他們只是感情好荷鼠,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,618評論 6 397
  • 文/花漫 我一把揭開白布句携。 她就那樣靜靜地躺著,像睡著了一般允乐。 火紅的嫁衣襯著肌膚如雪矮嫉。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,246評論 1 308
  • 那天喳篇,我揣著相機(jī)與錄音敞临,去河邊找鬼。 笑死麸澜,一個(gè)胖子當(dāng)著我的面吹牛挺尿,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播炊邦,決...
    沈念sama閱讀 40,819評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼编矾,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了馁害?” 一聲冷哼從身側(cè)響起窄俏,我...
    開封第一講書人閱讀 39,725評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎碘菜,沒想到半個(gè)月后凹蜈,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,268評論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡忍啸,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,356評論 3 340
  • 正文 我和宋清朗相戀三年仰坦,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片计雌。...
    茶點(diǎn)故事閱讀 40,488評論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡悄晃,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出凿滤,到底是詐尸還是另有隱情妈橄,我是刑警寧澤,帶...
    沈念sama閱讀 36,181評論 5 350
  • 正文 年R本政府宣布翁脆,位于F島的核電站眷蚓,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏鹃祖。R本人自食惡果不足惜溪椎,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,862評論 3 333
  • 文/蒙蒙 一普舆、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧校读,春花似錦沼侣、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,331評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至雁芙,卻和暖如春轧膘,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背兔甘。 一陣腳步聲響...
    開封第一講書人閱讀 33,445評論 1 272
  • 我被黑心中介騙來泰國打工谎碍, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人洞焙。 一個(gè)月前我還...
    沈念sama閱讀 48,897評論 3 376
  • 正文 我出身青樓蟆淀,卻偏偏與公主長得像,于是被迫代替她去往敵國和親澡匪。 傳聞我的和親對象是個(gè)殘疾皇子熔任,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,500評論 2 359

推薦閱讀更多精彩內(nèi)容