美文网首页我爱编程
django 实践练习

django 实践练习

作者: 两分与桥 | 来源:发表于2018-05-27 08:20 被阅读238次

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"),
]

视图函数

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>结果:</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>结果:</h3>
        {% for foo in video_list %}
            <div>{{ foo.title }}</div>
        {% endfor %}

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

表函数,

# 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='状态',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='权重(按从大到小排列)',default=0)
    title = models.CharField(verbose_name='标题',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 文件渲染出来的。



瀑布流

也就是在页面设置几个竖直的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; // 这里设置了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)
    视频列表:
        视频一,视频二
二、瀑布流


瀑布流,升级版

监听滑轮事件,使得滑轮滑到最底下时,触发请求图片事件,使得不断出现新的图片。

# 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 导航也是相同的
    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() {  // 触发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() {  // 鼠标滑轮事件
            $(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){ // 满足条件时,到达最低部
                    initImg();
                }
            })
        }
    </script>
</body>
</html>

1.png

不过这个 javascript 出现了全局变量,为了避免冲突,应该在外面封装函数或对象,将其封装到里面,

改为这样

<!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;  // 到函数内部的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>

写成一个类的形式,封装所有的变量和函数,但是要十分注意this,that。
效果是一模一样的。

note

一、瀑布流作业
    - 布局
    - 文档,窗口,滚动
    - 面向对象的封装: this,that
    
二、报障系统
    需求分析
        - 报障
            用户:
                提交报账单
                自己报障记录
            处理着:
                查看所有人报障单
                处理报账单
                
        - 知识库(博客)
            主页:
                展示最新文章
                展示最热文章
                展示评论最多文章
                分类查看
            个人博客:
                个人博客主页
                个人博客文章详细:赞,踩,评论
                个人博客分类:标签、分类、时间
                个人博客主题定制:后台修改
            后台管理:
                个人信息管理
                个人标签
                个人分类
                个人文章
            
    数据库设计:
        
        用户表: 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(待处理,处理中,已处理)  创建时间  处理事件
        
        
        分类表:caption  Fk(博客bid)
        
        标签表:caption  Fk(博客bid)
        
        
        文章:id,title,summary,ctime,FK(个人分类表),主站分类(choices)
        
        文章详细:detail  OneToOne(文章)
        
        文章标签关系:  文章ID   标签ID
        
        
        赞踩文章关系: 文章ID    用户ID   赞或踩(True,False)  联合唯一索引:(文章ID    用户ID )
        
        评论表:id,content,FK(文章),FK(user),ctime,parent_comment_id
        
        
        
三、程序目录结构

    project
        - APP(repository) - 数据仓库(操作数据Model)
        - APP(backend)    - 后台管理
        - APP(web)        - 首页,个人博客
        - utils           - 工具包(公共模块)
        

        
        
工作安排:
    1. 需求分析
    2. 数据库设计思路
    3. 实现数据库设计(Admin添加数据)
    4. 主站:分类(主站)查看+分页
        - 标题菜单:母版
        - 登录成功: session['username'] = 'root'
        - 主页html:
                判断是否有用户:显示用户名
                否则          : 登录,注册
                <div class="pg-header">
                    {% if request.session.username %}
                        <a>{{ request.session.username }}</a>
                    {% else %}
                        <a>登录</a><a>注册</a>
                    {% endif %}
                </div>
                    
        - 博文内容布局:
                div   div  -> float   => 图片下方空白
                <a></a>asdflkjasdfkj  => 文字环绕
        - URL分类筛选:
            url(r'^all/(?P<article_type_id>\d+).html$', home.index, name='index'),
            url(r'^', home.index),
        
            index根据kwargs判断是否分类查询?
            a. 生成分类菜单
            b. 考虑是否选中
            c. 根据条件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. 登录,注册
        - 密码:数字,字母,特殊字符
        - 密码两次输入一致
        
        提交:
            v = MyForm(request.GET) # 6个字段
            if v.is_valid():
                pass
        
        密码示例:RegexField自定义密码验证规则
        
            password = forms.RegexField(
                '^(?=.*[0-9])(?=.*[a-zA-Z])(?=.*[!@#$\%\^\&\*\(\)])[0-9a-zA-Z!@#$\%\^\&\*\(\)]{8,32}$',
                min_length=12,
                max_length=32,
                error_messages={'required': '密码不能为空.',
                                'invalid': '密码必须包含数字,字母、特殊字符',
                                '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}}

相关文章

网友评论

    本文标题:django 实践练习

    本文链接:https://www.haomeiwen.com/subject/xnzvjftx.html