django 實踐練習(xí)

django 組合搜索

# urls.py
from django.contrib import admin
from django.urls import path
from django.conf.urls import url
from app01 import views

urlpatterns = [
    path('admin/', admin.site.urls),
    url(r'^video-(?P<Classification_id>(\d+))-(?P<level_id>(\d+))-(?P<status>(\d+)).html$', views.video),
    url(r'^video2-(?P<direction_id>(\d+))-(?P<Classification_id>(\d+))-(?P<level_id>(\d+)).html$', views.video2,name="video2"),
]

視圖函數(shù)

from django.shortcuts import render
from django.shortcuts import HttpResponse
from app01 import models

def video(request,*args,**kwargs):
    print("kwargs::",kwargs)
    condition = {}
    for k,v in kwargs.items():
        temp = int(v)
        kwargs[k] = temp
        if temp:
            condition[k] = temp
    class_list = models.Classification.objects.all()
    level_list = models.Level.objects.all()

    video_list = models.Video.objects.filter(**condition)
    status_list = list(map(lambda x:{'id':x[0],"name":x[1]},models.Video.status_choice))
    print(status_list)
    return render(
        request,
        "video.html",
        {
            "class_list":class_list,
            "level_list":level_list,
            "kwargs":kwargs,
            "video_list":video_list,
            "status_list":status_list,
         }
    )

def video2(request,*args,**kwargs):
    condition = {}
    print("=-------------------------",kwargs)
    for k,v in kwargs.items():
        kwargs[k] = int(v)

    direction_id = kwargs.get("direction_id")
    classification_id = kwargs.get("Classification_id")
    level_id = kwargs.get("level_id")

    direction_list = models.Direction.objects.all()
    level_list = models.Level.objects.all()

    if direction_id == 0:
        class_list = models.Classification.objects.all()
        if classification_id == 0:
            pass
        else:
            condition['Classification_id'] = classification_id
    else:
        direction_obj = models.Direction.objects.filter(id=direction_id).first()
        class_list = direction_obj.classification.all()

        vlist = direction_obj.classification.all().values_list('id')
        if not vlist:
            classification_id_list = []
        else:
            classification_id_list = list(zip(*vlist))[0]

        if classification_id == 0:
            condition['Classification_id__in'] = classification_id_list
        else:
            if classification_id in classification_id_list:
                condition['Classification_id'] = classification_id
            else:
                #################指定方向:[1,2,3]   分類:5
                kwargs["Classification_id"] = 0
                condition['Classification_id__in'] = classification_id_list

    if level_id == 0:
        pass
    else:
        condition['level_id'] = level_id
    video_list = models.Video.objects.filter(**condition)
    return render(
        request,
        "video2.html",
        {
            "direction_list":direction_list,
            "class_list":class_list,
            "level_list":level_list,
            "video_list":video_list,
            "kwargs":kwargs,
        }
    )

模版文件 video.py 和 video2.py

# video.py
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .condition a{
            display: inline-block;
            padding: 5px 8px;
            border: 1px solid #dddddd;
        }
        .condition a.active{
            background-color: coral;
            color: white;
        }
    </style>
</head>
<body class="condition">
    <h3>篩選</h3>
    <div>
        {% if kwargs.Classification_id == 0 %}
            <a class="active" href="video-0-{{ kwargs.level_id }}-{{ kwargs.status }}.html">全部</a>
        {% else %}
            <a href="video-0-{{ kwargs.level_id }}-{{ kwargs.status }}.html">全部</a>
        {% endif %}
        {% for foo in class_list %}
            {% if kwargs.Classification_id == foo.id %}
                <a href="video-{{ foo.id }}-{{ kwargs.level_id }}-{{ kwargs.status }}.html" class="active">{{ foo.name }}</a>
            {% else %}
                <a href="video-{{ foo.id }}-{{ kwargs.level_id }}-{{ kwargs.status }}.html">{{ foo.name }}</a>
            {% endif %}
        {% endfor %}
    </div>

    <div>
        {% if kwargs.level_id == 0 %}
            <a class="active" href="video-{{ kwargs.Classification_id }}-0-{{ kwargs.status }}.html">全部</a>
        {% else %}
            <a href="video-{{ kwargs.Classification_id }}-0-{{ kwargs.status }}.html">全部</a>
        {% endif %}
        {% for foo in level_list %}
            {% if foo.id == kwargs.level_id %}
                <a href="video-{{ kwargs.Classification_id }}-{{ foo.id }}-{{ kwargs.status }}.html" class="active">{{ foo.title }}</a>
            {% else %}
                <a href="video-{{ kwargs.Classification_id }}-{{ foo.id }}-{{ kwargs.status }}.html">{{ foo.title }}</a>
            {% endif %}
        {% endfor %}

    </div>
        <div>
        {% if kwargs.status == 0 %}
            <a class="active" href="video-{{ kwargs.Classification_id }}-{{ kwargs.level_id }}-0.html">全部</a>
        {% else %}
            <a href="video-{{ kwargs.Classification_id }}-{{ kwargs.level_id }}-0.html">全部</a>
        {% endif %}
        {% for foo in status_list %}
            {% if foo.id == kwargs.status %}
                <a href="video-{{ kwargs.Classification_id }}-{{ kwargs.level_id }}-{{ foo.id }}.html" class="active">{{ foo.name }}</a>
            {% else %}
                <a href="video-{{ kwargs.Classification_id }}-{{ kwargs.level_id }}-{{ foo.id }}.html">{{ foo.name }}</a>
            {% endif %}
        {% endfor %}

    </div>
    <div>
        <h3>結(jié)果:</h3>
        {% for foo in video_list %}
            <div>{{ foo }}</div>
        {% endfor %}
    </div>
</body>
</html>

# video2.py
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .condition a{
            display: inline-block;
            padding: 5px 8px;
            border: 1px solid #dddddd;
        }
        .condition a.active{
            background-color: coral;
            color: white;
        }
    </style>
</head>
<body class="condition">
    <h3>篩選</h3>

    <div>
        {% if kwargs.direction_id == 0 %}
            <a href="{% url "video2" direction_id=0 Classification_id=kwargs.Classification_id level_id=kwargs.level_id %}" class="active">全部</a>
        {% else %}
            <a href="{% url "video2" direction_id=0 Classification_id=kwargs.Classification_id level_id=kwargs.level_id %}">全部</a>
        {% endif %}
        {% for foo in direction_list %}
            {% if foo.id == kwargs.direction_id %}
                <a href="{% url "video2" direction_id=foo.id Classification_id=kwargs.Classification_id level_id=kwargs.level_id %}" class="active">{{ foo.name }}</a>
            {% else %}
                <a href="{% url "video2" direction_id=foo.id Classification_id=kwargs.Classification_id level_id=kwargs.level_id %}">{{ foo.name }}</a>
            {% endif %}

        {% endfor %}
    </div>

    <div>
        {% if kwargs.Classification_id == 0 %}
            <a href="{% url "video2" direction_id=kwargs.direction_id Classification_id=0 level_id=kwargs.level_id %}" class="active">全部</a>
        {% else %}
            <a href="{% url "video2" direction_id=kwargs.direction_id Classification_id=0 level_id=kwargs.level_id %}">全部</a>
        {% endif %}
        {% for foo in class_list %}
            {% if foo.id == kwargs.Classification_id %}
                <a href="/video2-{{ kwargs.direction_id }}-{{ foo.id }}-{{ kwargs.level_id }}.html" class="active">{{ foo.name }}</a>
            {% else %}
                <a href="/video2-{{ kwargs.direction_id }}-{{ foo.id }}-{{ kwargs.level_id }}.html">{{ foo.name }}</a>
            {% endif %}
        {% endfor %}
    </div>

    <div>
        {% if kwargs.level_id == 0 %}
            <a href="{% url "video2" direction_id=kwargs.direction_id Classification_id=kwargs.Classification_id level_id=0 %}" class="active">全部</a>
        {% else %}
            <a href="{% url "video2" direction_id=kwargs.direction_id Classification_id=kwargs.Classification_id level_id=0 %}">全部</a>
        {% endif %}
        {% for foo in level_list %}
            {% if foo.id == kwargs.level_id %}
                <a href="/video2-{{ kwargs.direction_id }}-{{ kwargs.Classification_id }}-{{ foo.id }}.html" class="active">{{ foo.title }}</a>
            {% else %}
                <a href="/video2-{{ kwargs.direction_id }}-{{ kwargs.Classification_id }}-{{ foo.id }}.html">{{ foo.title }}</a>
            {% endif %}
        {% endfor %}
    </div>

    <div>
        <h3>結(jié)果:</h3>
        {% for foo in video_list %}
            <div>{{ foo.title }}</div>
        {% endfor %}

    </div>
</body>
</html>

表函數(shù),

# models.py 
from django.db import models

class Direction(models.Model):
    """
    方向:自動化,測試,運維,前端
    """
    name = models.CharField(verbose_name='名稱',max_length=32)

    classification = models.ManyToManyField("Classification")
    class Meta:
        db_table = 'Direction'
        verbose_name_plural = "方向(視頻方向)"
    def __str__(self):
        return self.name

class Classification(models.Model):
    """
    分類: Python Linux JavaScript OpenStack Node.js
    """
    name = models.CharField(verbose_name='名稱',max_length=32)
    class Meta:
        db_table = "Classification"
        verbose_name_plural = "分類(視頻分類)"
    def __str__(self):
        return self.name

class Level(models.Model):
    title = models.CharField(max_length=32)
    class Meta:
        verbose_name_plural = '難度級別'
    def __str__(self):
        return self.title

class Video(models.Model):
    status_choice = (
        (1,'下線'),
        (2,'上線'),
    )
    status = models.IntegerField(verbose_name='狀態(tài)',choices=status_choice,default=1)
    level = models.ForeignKey(Level,on_delete=models.CASCADE)
    Classification = models.ForeignKey('Classification',null=True,blank=True,on_delete=models.CASCADE)
    weight = models.IntegerField(verbose_name='權(quán)重(按從大到小排列)',default=0)
    title = models.CharField(verbose_name='標(biāo)題',max_length=32)
    summary = models.CharField(verbose_name='簡介',max_length=32)

    img = models.CharField(verbose_name='圖片',max_length=32)
    href = models.CharField(verbose_name='圖片地址',max_length=256)

    create_date = models.DateTimeField(auto_now_add=True)

    class Meta:
        db_table = 'Video'
        verbose_name_plural = '視頻'
    def __str__(self):
        return self.title

這個是 video2.html 文件渲染出來的。



瀑布流

也就是在頁面設(shè)置幾個豎直的div框,讓圖片分別排列,就形成了瀑布流的效果了。

# 用的還是上面的那張表,
# views.py
def image(request):
    return render(request,"image.html")

def get_images(request):
    image_list = models.Imgs.objects.all().values("id","src","title")
    image_list = list(image_list)
    ret = {
        "status": True,
        "data": image_list,
    }
    return HttpResponse(json.dumps(ret))

# urls.py 中要添加這兩句
    path('image/', views.image),
    path('get_images.html/', views.get_images),

所有的排列都在js里

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .w{
            width: 1000px;
            margin: 0 auto;
        }
        .w .item{
            width: 25%;
            float: left;
        }
        img{
            width: 95%;
        }
    </style>
</head>
<body>
    <div class="w" id="container">
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
    </div>

    <script src="/static/jquery-3.3.1.min.js"></script>
    <script>
        $(function () {
            initImg();
        });
        function initImg() {
            $.ajax({
                url: "/get_images.html",
                type: "GET",
                data: {nid:1213},
                dataType: "JSON",
                success:function (arg) {
                    var image_list = arg.data;
                    $.each(image_list,function (index,v) {
                        var eqv = index%4; // 這里設(shè)置了4個div,
                        var tag = document.createElement("img");
                        tag.src = '/' + v.src;
                        $("#container").children().eq(eqv).append(tag);
                    });
                }
            })
        }
    </script>
</body>
</html>

效果看起來倒是很不錯了,


1.png
一、組合搜索
    方向:自動化*,測試,運維[4,5],前端
    分類:Python* Linux OpenStack  [1,2,3]
    級別:初級 中級 高級
    
    condition = {}
    
    models.Video.objects.filter(**condition)
    視頻列表:
        視頻一,視頻二
二、瀑布流


瀑布流,升級版

監(jiān)聽滑輪事件,使得滑輪滑到最底下時,觸發(fā)請求圖片事件,使得不斷出現(xiàn)新的圖片。

# views.py 基本不用怎么改 ,
def image(request):
    return render(request,"image.html")

def get_images(request):
    nid = request.GET.get('nid')
    image_list = models.Imgs.objects.all().values("id","src","title")
    image_list = list(image_list)
    ret = {
        "status": True,
        "data": image_list,
    }
    print("nid=",nid)
    return HttpResponse(json.dumps(ret))

# urls.py 導(dǎo)航也是相同的
    path('image/', views.image),
    path('get_images.html/', views.get_images),

image.html 模版文件,

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .w{
            width: 1000px;
            margin: 0 auto;
        }
        .w .item{
            width: 25%;
            float: left;
        }
        img{
            width: 95%;
        }
    </style>
</head>
<body>
    <div class="w" id="container">
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
    </div>

    <script src="/static/jquery-3.3.1.min.js"></script>
    <script>
        $(function () {
            initImg();
            scollEvent();
        });
        nid=0;
        last_position = 0;
        function initImg() {  // 觸發(fā)ajax請求圖片,也就是圖片路徑
            $.ajax({
                url: "/get_images.html",
                type: "GET",
                data: {nid:nid},
                dataType: "JSON",
                success:function (arg) {
                    var image_list = arg.data;
                    $.each(image_list,function (index,v) {
                        var eqv = (index+last_position)%4;
                        console.log(eqv);
                        var tag = document.createElement("img");
                        tag.src = '/' + v.src;
                        $("#container").children().eq(eqv).append(tag);
                        if(index+1 == image_list.length){
                            nid=nid+v.id;
                            last_position=eqv+1;  // 我們必須保留上一次的求余
          // 使得下次ajax請求時圖片從上次空缺的位置放起 
                        }
                    });
                }
            })
        }
        
        function scollEvent() {  // 鼠標(biāo)滑輪事件
            $(window).scroll(function () {
                var doc_height = $(document).height();  // 文檔高度
                var window_height = $(window).height();  // 窗口高度 
                var scroll_top = $(window).scrollTop();      // 滑動條滑動高度
                if(doc_height==window_height+scroll_top){ // 滿足條件時,到達(dá)最低部
                    initImg();
                }
            })
        }
    </script>
</body>
</html>

1.png

不過這個 javascript 出現(xiàn)了全局變量,為了避免沖突,應(yīng)該在外面封裝函數(shù)或?qū)ο螅瑢⑵浞庋b到里面,

改為這樣

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .w{
            width: 1000px;
            margin: 0 auto;
        }
        .w .item{
            width: 25%;
            float: left;
        }
        img{
            width: 95%;
        }
    </style>
</head>
<body>
    <div class="w" id="container">
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
    </div>

    <script src="/static/jquery-3.3.1.min.js"></script>
    <script>
        $(function () {
            var obj = new allEvent();
            obj.initImg();
            obj.scollEvent();
        });

        function allEvent() {
            this.nid = 0;
            this.last_position = 0;
            var that = this;  // 到函數(shù)內(nèi)部的this和外部的this是不相同的,所以需要保留這個this
            this.initImg = function () {
            $.ajax({
                url: "/get_images.html",
                type: "GET",
                data: {nid:that.nid},
                dataType: "JSON",
                success:function (arg) {
                    var image_list = arg.data;
                    $.each(image_list,function (index,v) {
                        var eqv = (index+that.last_position)%4;
                        console.log(eqv);
                        var tag = document.createElement("img");
                        tag.src = '/' + v.src;
                        $("#container").children().eq(eqv).append(tag);
                        if(index+1 == image_list.length){
                            that.nid=that.nid+v.id;
                            that.last_position=eqv+1;
                        }
                    });
                }
            })
        };

            this.scollEvent = function () {
                $(window).scroll(function () {
                var scroll_height = $(document).height();
                var window_height = $(window).height();
                var scroll_top = $(window).scrollTop();
                if(scroll_height==window_height+scroll_top){
                    that.initImg();
                }
            })
            }
        }

    </script>
</body>
</html>

寫成一個類的形式,封裝所有的變量和函數(shù),但是要十分注意this,that。
效果是一模一樣的。

note

一、瀑布流作業(yè)
    - 布局
    - 文檔,窗口,滾動
    - 面向?qū)ο蟮姆庋b: this,that
    
二、報障系統(tǒng)
    需求分析
        - 報障
            用戶:
                提交報賬單
                自己報障記錄
            處理著:
                查看所有人報障單
                處理報賬單
                
        - 知識庫(博客)
            主頁:
                展示最新文章
                展示最熱文章
                展示評論最多文章
                分類查看
            個人博客:
                個人博客主頁
                個人博客文章詳細(xì):贊,踩,評論
                個人博客分類:標(biāo)簽、分類、時間
                個人博客主題定制:后臺修改
            后臺管理:
                個人信息管理
                個人標(biāo)簽
                個人分類
                個人文章
            
    數(shù)據(jù)庫設(shè)計:
        
        用戶表: uid,username,pwd,email,img,
        博客表: bid,surfix,theme,title,summary, FK(用戶表,unique)=OneToOne(用戶表)
        互粉表: id  明星ID(用戶表)   粉絲ID(用戶表)
                          2                   1
                          1                   2
                          1                   3
                          5                   3
        
        
        報障單:UUID   title   detail   user(用戶表)   processor(用戶表 null)  status(待處理,處理中,已處理)  創(chuàng)建時間  處理事件
        
        
        分類表:caption  Fk(博客bid)
        
        標(biāo)簽表:caption  Fk(博客bid)
        
        
        文章:id,title,summary,ctime,FK(個人分類表),主站分類(choices)
        
        文章詳細(xì):detail  OneToOne(文章)
        
        文章標(biāo)簽關(guān)系:  文章ID   標(biāo)簽ID
        
        
        贊踩文章關(guān)系: 文章ID    用戶ID   贊或踩(True,F(xiàn)alse)  聯(lián)合唯一索引:(文章ID    用戶ID )
        
        評論表:id,content,FK(文章),FK(user),ctime,parent_comment_id
        
        
        
三、程序目錄結(jié)構(gòu)

    project
        - APP(repository) - 數(shù)據(jù)倉庫(操作數(shù)據(jù)Model)
        - APP(backend)    - 后臺管理
        - APP(web)        - 首頁,個人博客
        - utils           - 工具包(公共模塊)
        

        
        
工作安排:
    1. 需求分析
    2. 數(shù)據(jù)庫設(shè)計思路
    3. 實現(xiàn)數(shù)據(jù)庫設(shè)計(Admin添加數(shù)據(jù))
    4. 主站:分類(主站)查看+分頁
        - 標(biāo)題菜單:母版
        - 登錄成功: session['username'] = 'root'
        - 主頁html:
                判斷是否有用戶:顯示用戶名
                否則          : 登錄,注冊
                <div class="pg-header">
                    {% if request.session.username %}
                        <a>{{ request.session.username }}</a>
                    {% else %}
                        <a>登錄</a><a>注冊</a>
                    {% endif %}
                </div>
                    
        - 博文內(nèi)容布局:
                div   div  -> float   => 圖片下方空白
                <a></a>asdflkjasdfkj  => 文字環(huán)繞
        - URL分類篩選:
            url(r'^all/(?P<article_type_id>\d+).html$', home.index, name='index'),
            url(r'^', home.index),
        
            index根據(jù)kwargs判斷是否分類查詢?
            a. 生成分類菜單
            b. 考慮是否選中
            c. 根據(jù)條件model.xxx.objects.filter(**kwargs)
            
        - URL:
            from django.urls import reverse
            
            url(r'^all/(?<article_type_id>\d+).html$', home.index, name='index'),
                在HTML中:{% url "index" article_type_id=1 %}             => all/1.html
                在views中:reverse('index',kwargs={"article_type_id":1})  =>all/1.html
            
            url(r'^all/(\d+).html$', home.index, name='index'),
                在HTML中:{% url "index" 1 %}          =>all/1.html
                在views中:reverse('index',args=(1,))  =>all/1.html
        
        - 利用reverse+分頁組件完成:分類查看+分頁 
        
  5. 登錄,注冊
        - 密碼:數(shù)字,字母,特殊字符
        - 密碼兩次輸入一致
        
        提交:
            v = MyForm(request.GET) # 6個字段
            if v.is_valid():
                pass
        
        密碼示例:RegexField自定義密碼驗證規(guī)則
        
            password = forms.RegexField(
                '^(?=.*[0-9])(?=.*[a-zA-Z])(?=.*[!@#$\%\^\&\*\(\)])[0-9a-zA-Z!@#$\%\^\&\*\(\)]{8,32}$',
                min_length=12,
                max_length=32,
                error_messages={'required': '密碼不能為空.',
                                'invalid': '密碼必須包含數(shù)字,字母、特殊字符',
                                'min_length': "密碼長度不能小于8個字符",
                                'max_length': "密碼長度不能大于32個字符"}
            )
              


            class RegisterForm(BaseForm, django_forms.Form):
                username = django_fields.CharField()
                password = django_fields.CharField()
                confirm_pwd = django_fields.CharField()

                def clean(self):
                    v1 = self.cleaned_data['password']
                    v2 = self.cleaned_data['confirm_pwd']
                    if v1 == v2:
                        pass
                    else:
                        from django.core.exceptions import ValidationError
                        raise ValidationError('密碼輸入不一致')
        
            
            def register(request):
                v = RegisterForm(request.POST)
                if v.is_valid():
                    pass
                else:
                    v.errors['username']
                    v.errors['__all__']
                    v.errors[NON_FIELD_ERRORS]
                    {
                        __all__: [],
                        username: [],
                        password: []
                        confirm_pwd: []
                    }
                
                return render(request, 'register.html', {'v':v})
                
                
            register.html
            
                {{v.errors.username.0}}
                
                {{v.non_field_errors}}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容