1. 程式人生 > 其它 >BBS專案分佈搭建二(個人站點相關)

BBS專案分佈搭建二(個人站點相關)

BBS專案分佈搭建二

1. 首頁詳情補充

# 在home.html檔案中 body標籤內補充:


<div class="container-fluid">
    <div class="row">
        
        
        <div class="col-md-2">
            <div class="panel panel-primary">
                <div class="panel-body">
                    Panel content
                </div>
                <div class="panel-footer">Panel footer</div>
            </div>

            <div class="panel panel-success">
                <div class="panel-body">
                    Panel content
                </div>
                <div class="panel-footer">Panel footer</div>
            </div>

            <div class="panel panel-danger">
                <div class="panel-body">
                    Panel content
                </div>
                <div class="panel-footer">Panel footer</div>
            </div>
        </div>


        <div class="col-md-8">
            <div class="media">
                <h4 class="media-heading"><a href="">世界那麼大 我想去看看</a></h4>
                <div class="media-left">
                    <a href="#">
                        <img class="media-object" style="width: 80px;" src="/static/img/default.jpg"
                             alt="...">
                    </a>
                </div>

                <div class="media-body">
                    這是一篇自我介紹的破冰帖 最近我很苦惱,我們團隊的小姐姐們都在社群收穫良多,做的活動鑼鼓喧天,熱鬧非凡 而我看看自己寥寥無幾的工作成果,覺得他們十分聒噪(bushi)
                    再加上近期被我騷擾過的大佬們都已經不回覆我了,生鏽了20多年的腦袋突然靈光一閃 那我可以讓你們來找我啊! 哼哼哼……那啥
                </div>

                {#                 Code綜藝圈#}
                {#                2022-03-15 08:50#}
                {#                1#}
                {#                1#}
                {#                100#}
                <div id="wrapper" style="margin-top: 15px">
                    <span><a href="">Code綜藝圈</a></span>
                    <span>2022-03-15 08:50</span>
                    <span class="glyphicon glyphicon-thumbs-up">1</span>
                    <span class="glyphicon glyphicon-thumbs-down">2</span>
                    <span class="glyphicon glyphicon-comment">3</span>
                </div>
            </div>
            <hr>
        </div>



        <div class="col-md-2">
            <div class="panel panel-primary">
                <div class="panel-body">
                    Panel content
                </div>
                <div class="panel-footer">Panel footer</div>
            </div>

            <div class="panel panel-success">
                <div class="panel-body">
                    Panel content
                </div>
                <div class="panel-footer">Panel footer</div>
            </div>

            <div class="panel panel-danger">
                <div class="panel-body">
                    Panel content
                </div>
                <div class="panel-footer">Panel footer</div>
            </div>

        </div>


    </div>
</div>

2. 模擬產生資料

# 建立後臺管理員系統所需的表
在 admin.py檔案中寫入程式碼:

from django.contrib import admin

# Register your models here.

from app01 import models
# 註冊資料表
admin.site.register(models.UserInfo)
admin.site.register(models.Blog)
admin.site.register(models.Tag)
admin.site.register(models.Category)
admin.site.register(models.Article)
admin.site.register(models.Article2Tag)
admin.site.register(models.UpAndDown)
admin.site.register(models.Comment)



# 登入後臺管理員系統
"""由於表名都是英文的 可以自行改為中文 在每個表下面加上 class Meta 即可"""

### 在 models.py檔案中修改表配置:
from django.contrib.auth.models import AbstractUser

# 1. 使用者表
class UserInfo(AbstractUser):
    phone = models.CharField(max_length=32, verbose_name='手機號', default='', blank=True)
    '''
        default='' 指定的是資料庫中的預設值
        blank=True:django限制的必填項
        
    '''

    # 頭像
    avatar = models.FileField(upload_to='static/img', default='static/img/default.png')
    # 建立時間
    create_time = models.DateTimeField(auto_now_add=True)

    blog = models.OneToOneField(to='Blog', null=True)

    class Meta:
        # db_table = 'aaa'
        verbose_name = '使用者表'
        verbose_name_plural = verbose_name


# 2. 站點表
class Blog(models.Model):
    site_name = models.CharField(max_length=64, verbose_name='站點名稱')
    site_title = models.CharField(max_length=64, verbose_name='站點標題')
    site_style = models.CharField(max_length=64, verbose_name='站點樣式')

    class Meta:
        # verbose_name = '站點表'
        verbose_name_plural = '站點表'

    def __str__(self):
        return self.site_name


# 3. 標籤表
class Tag(models.Model):
    title = models.CharField(max_length=64, verbose_name='標籤名稱')

    def __str__(self):
        return self.title

    class Meta:
        verbose_name_plural = '標籤表'



# 4. 分類表
class Category(models.Model):
    title = models.CharField(max_length=64, verbose_name='分類名稱')

    class Meta:
        verbose_name_plural = '分類表'

    def __str__(self):
        return self.title


# 5. 文章表
class Article(models.Model):
    title = models.CharField(max_length=128, verbose_name='文章標題')
    desc = models.CharField(max_length=512, verbose_name='文章簡介')
    content = models.TextField(verbose_name='文章內容')
    create_time = models.DateTimeField(auto_now_add=True)


    # 外來鍵關係
    blog = models.ForeignKey(to='Blog')
    category = models.ForeignKey(to='Category')

    # 多對多
    tags = models.ManyToManyField(to='Tag',
                                  through='Article2Tag',
                                  through_fields=('article', 'tag'))

    # 優化欄位
    up_num = models.IntegerField(verbose_name='點贊數', default=0)
    down_num = models.IntegerField(verbose_name='點踩數', default=0)
    comment_num = models.IntegerField(verbose_name='評論數', default=0)

    def __str__(self):
        return self.title


class Article2Tag(models.Model):
    article = models.ForeignKey(to='Article')
    tag = models.ForeignKey(to='Tag')




# 6. 點贊點踩表
class UpAndDown(models.Model):
    user = models.ForeignKey(to='UserInfo')
    article = models.ForeignKey(to='Article')
    # 布林值:True/False  => 資料庫中顯示為: 1/0
    is_up = models.BooleanField()

    class Meta:
        verbose_name_plural = '點贊點踩表'



# 7. 評論表
class Comment(models.Model):
    user = models.ForeignKey(to='UserInfo')
    article = models.ForeignKey(to='Article')
    content = models.CharField(max_length=512, verbose_name='評論內容')
    create_time = models.DateTimeField(auto_now_add=True)

    # parent_id = models.ForeignKey(to='Comment')
    parent = models.ForeignKey(to='self')

    class Meta:
        verbose_name_plural = '評論表'
    

3. 首頁資料展示

# 在 views.py中修改:

# 4. 首頁
def home(request):
    article_list = models.Article.objects.all()
    return render(request, 'home.html', locals())



# 在home.html檔案中修改 <div class="col-md-8"> 即可:
<div class="col-md-8">
            {% for article in article_list %}
            <div class="media">
                <h4 class="media-heading"><a href="">{{ article.title }}</a></h4>
                <div class="media-left">
                    <a href="#">
                        <img class="media-object" style="width: 80px;" src="/{{ article.blog.userinfo.avatar }}"
                             alt="...">
                    </a>
                </div>

                <div class="media-body">
                    {{ article.desc }}
                </div>

                {#                 Code綜藝圈#}
                {#                2022-03-15 08:50#}
                {#                1#}
                {#                1#}
                {#                100#}
                <div id="wrapper" style="margin-top: 15px">
                    <span><a href="">{{ article.blog.userinfo.username }}</a></span>
                    <span>{{ article.create_time|date:'Y-m-d H:i' }}</span>
                    <span class="glyphicon glyphicon-thumbs-up">{{ article.up_num }}</span>
                    <span class="glyphicon glyphicon-thumbs-down">{{ article.down_num }}</span>
                    <span class="glyphicon glyphicon-comment">{{ article.comment_num }}</span>
                </div>
            </div>
            <hr>
            {% endfor %}
        </div>

4. 個人站點頁和404頁面搭建

 # 新增路由:
    # 個人站點頁,缺點:匹配的範圍太大,
    url(r'^(?P<username>\w+)/', views.blog),
    
    
# 在views.py中新增功能:
# 7.個人站點頁
def blog(request, username):
    '''
    驗證站點是否存在
    :param request:
    :param username:
    :return:
    '''

    # 驗證站點的存在性 404頁面
    user_obj = models.UserInfo.objects.filter(username=username).first()
    if not user_obj:
        # 應該返回定製的404頁面
        return render(request, '404.html')
    
    return render(request, 'blog.html')



# 新建blog.html檔案內容:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
    <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
    <script src="/static/layer-v3.5.1/layer/layer.js"></script>

    <style>
        #wrapper span {
            margin-right: 10px;
        }
    </style>
</head>
<body>

<nav class="navbar navbar-inverse">
    <div class="container-fluid">
        <!-- Brand and toggle get grouped for better mobile display -->
        <div class="navbar-header">
            <button type="button" class="navbar-toggle collapsed" data-toggle="collapse"
                    data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
                <span class="sr-only">Toggle navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
            <a class="navbar-brand" href="#">py20BBS</a>
        </div>

        <!-- Collect the nav links, forms, and other content for toggling -->
        <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">

            <ul class="nav navbar-nav">
                <li class="active"><a href="#">Link <span class="sr-only">(current)</span></a></li>
                <li><a href="#">Link</a></li>
                <li class="dropdown">
                    <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
                       aria-expanded="false">Dropdown <span class="caret"></span></a>
                    <ul class="dropdown-menu">
                        <li><a href="#">Action</a></li>
                        <li><a href="#">Another action</a></li>
                        <li><a href="#">Something else here</a></li>
                        <li role="separator" class="divider"></li>
                        <li><a href="#">Separated link</a></li>
                        <li role="separator" class="divider"></li>
                        <li><a href="#">One more separated link</a></li>
                    </ul>
                </li>


            </ul>
            <form class="navbar-form navbar-left">
                <div class="form-group">
                    <input type="text" class="form-control" placeholder="Search">
                </div>
                <button type="submit" class="btn btn-default">Submit</button>
            </form>
            <ul class="nav navbar-nav navbar-right">
                {% if request.session.username %}
                    <li><a href="#">{{ request.session.username }}</a></li>
                    <li class="dropdown">
                        <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
                           aria-expanded="false">更多操作 <span class="caret"></span></a>
                        <ul class="dropdown-menu">
                            <li><a href="#" data-toggle="modal" data-target=".bs-example-modal-lg">修改密碼</a></li>
                            <li><a href="#">後臺管理</a></li>
                            <li><a href="/logout/">退出系統</a></li>
                        </ul>
                    </li>
                {% else %}
                    <li><a href="/register/">註冊</a></li>
                    <li><a href="/login/">登入</a></li>
                {% endif %}

            </ul>
        </div><!-- /.navbar-collapse -->
        <div class="modal fade bs-example-modal-lg" tabindex="-1" role="dialog" aria-labelledby="myLargeModalLabel">
            <div class="modal-dialog modal-lg" role="document">
                <div class="modal-content">
                    <div class="row">
                        <h1 class="text-center">修改密碼</h1>
                        <div class="col-md-8 col-md-offset-2">
                            <div class="form-group">
                                <label for="old_pwd">
                                    原密碼:
                                </label>
                                <input type="text" id="old_pwd" class="form-control">
                            </div>
                            <div class="form-group">
                                <label for="new_pwd">
                                    新密碼:
                                </label>
                                <input type="text" id="new_pwd" class="form-control">
                            </div>
                            <div class="form-group">
                                <label for="re_pwd">確認密碼:</label>
                                <input type="text" id="re_pwd" class="form-control">
                            </div>
                            <div class="modal-footer">
                                <button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
                                <button type="button" class="btn btn-primary set_pwd">提交</button>
                            </div>
                        </div>

                    </div>
                </div>
            </div>
        </div>
    </div><!-- /.container-fluid -->
</nav>


<div class="container-fluid">
    <div class="row">
        
        <div class="col-md-3">
            <div class="panel panel-primary">
                <div class="panel-body">
                    Panel content
                </div>
                    <div class="panel-footer">
                        標籤
                    </div>
            </div>

            <div class="panel panel-success">
                <div class="panel-body">
                    Panel content
                </div>
                    <div class="panel-footer">
                        分類
                    </div>
            </div>

            <div class="panel panel-danger">
                <div class="panel-body">
                    Panel content
                </div>
                <div class="panel-footer">時間歸檔</div>
            </div>
        </div>


        <div class="col-md-9">
                <div class="media">
                    <h4 class="media-heading"><a href="">111</a></h4>

                    <div class="media-left">
                        <a href="">
                            <img class="media-object" style="width: 80px;" src="/{{ article.blog.userinfo.avatar }}"
                             alt="...">
                        </a>
                    </div>

                    <div class="media-body">
                        11111
                    </div>
                    
                    <div id="wrapper" class="pull-right" style="margin-top: 15px">
                        <span><a href="">222</a></span>
                        <span>333</span>
                        <span class="glyphicon glyphicon-thumbs-up">000</span>
                        <span class="glyphicon glyphicon-thumbs-down">555</span>
                        <span class="glyphicon glyphicon-comment">999</span>
                    </div>
                </div>
        </div>

        
    </div>
</div>

</body>
</html>



# 新建404.html檔案內容:
	可以直接複製任意網站404頁面內容拿來使用

5. 個人站點文章展示功能

# 7.個人站點頁
def blog(request, username):
    '''
    驗證站點是否存在
    :param request:
    :param username:
    :return:
    '''

    # 驗證站點的存在性 404頁面
    user_obj = models.UserInfo.objects.filter(username=username).first()
    if not user_obj:
        # 應該返回定製的404頁面
        return render(request, '404.html')

    blog = user_obj.blog  # 個人站點
    # 查詢當前站點的所有文章列表
    article_list = models.Article.objects.filter(blog=blog).all()
    
    return render(request, 'blog.html', locals())



# blog.html檔案只修改 <div class="col-md-9"> 即可:
        <div class="col-md-9">
            {% for article in article_list %}
                <div class="media">
                    <h4 class="media-heading"><a href="">{{ article.title }}</a></h4>


                    <div class="media-body">
                        {{ article.desc }}
                    </div>

                    <div id="wrapper" class="pull-right" style="margin-top: 15px">
                        <span>posted</span>
                        <span>@</span>
                        <span>{{ article.create_time|date:'Y-m-d H:i' }}</span>
                        <span class="glyphicon glyphicon-thumbs-up">{{ article.up_num }}</span>
                        <span class="glyphicon glyphicon-thumbs-down">{{ article.down_num }}</span>
                        <span class="glyphicon glyphicon-comment">{{ article.comment_num }}</span>
                    </div>
                </div>
            {% endfor %}

        </div>

6. 個人站點頁 標籤和分類展示

# 在models.py中 對分類表和標籤表建立外來鍵關係 之後重新遷移資料庫:
    blog = models.ForeignKey(to='Blog', null=True)  # 外來鍵
    
    
    
# 修改blog.html檔案中 <div class="col-md-3"> :
        <div class="col-md-3">
            <div class="panel panel-primary">
                <div class="panel-body">
                    我的標籤
                </div>

                {% for tag in tag_list %}
                <div class="panel-footer">
                    <a href="">{{ tag.title }}( {{ tag.count_num }})</a>
                </div>
                {% endfor %}
            </div>

            <div class="panel panel-success">
                <div class="panel-body">
                     我的分類
                </div>
                {% for category in category_list %}
                    <div class="panel-footer">
                        <a href="">{{ category.title }}({{ category.count_num }})</a>
                    </div>
                {% endfor %}
            </div>

            <div class="panel panel-danger">
                <div class="panel-body">
                    Panel content
                </div>
                <div class="panel-footer">時間歸檔</div>
            </div>
        </div>