欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Django之上传图片,分页,三级联动

程序员文章站 2022-03-21 21:37:02
Django之上传图片,分页,三级联动;其中,上传图片包括 配置上传文件保存目录,后台管理页面上传图片,用户自定义页面上传图片及对应实例代码;分页包括 分页实例;三级联动包括 三级联动实例。 ......

django1.8.2中文文档:django1.8.2中文文档

上传图片

配置上传文件保存目录

1)新建上传文件保存目录。

Django之上传图片,分页,三级联动

2)配置上传文件保存目录。

Django之上传图片,分页,三级联动

 

后台管理页面上传图片

  • 1)设计模型类。
  • 2)迁移生成表格。
  • 3) 注册模型类。

 

后台管理页面上传图片实例

1.在static下面创建media文件夹(再在media文件夹里面新建booktest文件夹)。

2.设置静态文件保存目录

# 设置上传文件的保存目录
media_root = os.path.join(base_dir, 'static/media')

3.编写图片模型类

class pictest(models.model):
    """上传图片"""
    goods_pic = models.imagefield(upload_to='booktest')  # 指定上传图片到media下面的booktest文件夹下

4.迁移数据

python manage.py makemigrations
python manage.py migrate

如果项目用的是原来的数据库,那么应该先去django_migrations里面删除booktest的init文件;

delete from django_migrations where id = xxx;

如果数据库中原来存在areainfo表,然后项目中的模型类又申请创建,会报错,
解决方法是去booktets/migrations/001init下面删掉重复的表记录。

5.去admin中注册表

admin.site.register(models.pictest)

这时候,就可以在后台上传图片了。

 

用户自定义页面上传图片

  • 1)定义用户上传图片的页面并显示,是一个自定义的表单。
  • 2)定义接收上传文件的视图函数。

request对象有一个files的属性,类似于字典,通过request.files可以获取上传文件的处理对象

在django中,上传文件不大于2.5m,文件放在内存中。上传文件大于2.5m,文件内容写到一个临时文件中。
django处理上传文件的两个类:

file_upload_handlers= (
"django.core.files.uploadhandler.memoryfileuploadhandler", "django.core.files.uploadhandler.temporaryfileuploadhandler")

 

用户自定义页面上传图片实例

上传图片html--upload_pic.html

<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>上传图片</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<form action="/upload_handle/" method="post" enctype="multipart/form-data">
    {% csrf_token %}
    <input type="file" name="pic"><br>
    <input type="submit" value="上传图片">
</form>

</body>
</html>

上传图片对应函数

from django.conf import settings  # 上传图片时使用
def upload_pic(request):
    """返回上传图片文件的页面"""
    return render(request, 'booktest/upload_pic.html')


def upload_handle(request):
    """对上传的文件进行处理"""
    # 1.获取上传文件的处理对象
    pic = request.files['pic']
    pic_name = pic.name  # 上传文件名
    # pic.chunk()  # 上传的文件会以迭代器的形式,一部分一部分的保存在这里面
    # 2.创建一个文件
    save_path = '%s/booktest/%s' % (settings.media_root, pic_name)
    # 3.将上传的文件写入到新创建的文件中
    with open(save_path, 'wb') as f:
        for content in pic.chunks():
            f.write(content)
    # 4.记录写入数据库
    models.pictest.objects.create(goods_pic='booktest/%s' % pic_name)
    # 5.返回应答
    return httpresponse(pic_name)

配套url

url(r'^upload_pic', views.upload_pic),  # 返回上传图片文件的页面
url(r'^upload_handle', views.upload_handle),  # 对上传的文件进行处理

 

分页

需求

查询出所有省级地区的信息,显示在页面上。
1)查询出所有省级地区的信息。
2)按每页显示10条信息进行分页,默认显示第一页的信息,下面并显示出页码。
3)点击i页链接的时候,就显示第i页的省级地区信息。

 

分页实例

url

url(r'^show_areas(?p<pindex>\d*)', views.show_areas),  # 分页

show_areas.html

<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>分页</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>

<ul>
    {% for area in page %}
        <li>{{ area.atitle }}</li>
    {% endfor %}
</ul>

{% if page.has_previous %}
    <a href="/show_areas{{ page.previous_page_number }}">&lt;上一页</a>
{% endif %}

{% for pindex in page.paginator.page_range %}
    {% if pindex == page.number %}
        {{ pindex }}
    {% else %}
        <a href="/show_areas{{ pindex }}">{{ pindex }}</a>
    {% endif %}
{% endfor %}

{% if page.has_next %}
    <a href="/show_areas{{ page.next_page_number }}">下一页&gt;</a>
{% endif %}

</body>
</html>

分页对应函数

from django.core.paginator import paginator

def show_areas(request, pindex):
    """分页"""
    # 1.查询出所有省级地区的信息
    areas = models.areainfo.objects.filter(aparent__isnull=true)
    # 2.分页,每页显示10条
    pagintor = paginator(areas, 10)
    # 3.获取第pindex页的内容
    if pindex == "":
        # 默认取第一页的内容
        pindex = 1
    else:
        pindex = int(pindex)
    # page是page类的实例对象
    page = pagintor.page(pindex)

    # 4.使用模板
    return render(request, 'booktest/show_areas.html', {'page': page})

 

 

三级联动

需求

1)显示省地区信息。
2)省改变时在对应的下拉列表框中显示下级市的信息。
3)市改变时在对应的下拉列表框中显示下级县的信息。

 

三级联动实例

对应函数

def areas(request):
    return render(request, 'booktest/areas.html')


def prov(request):
    """返回省级数据"""
    # 1.获取所有省级地区的信息
    areas = models.areainfo.objects.filter(aparent__isnull=true)
    # 2.变量areas拼接处json数据:atitle,id
    areas_list = []
    for area in areas:
        areas_list.append((area.id, area.atitle))
    return jsonresponse({'data': areas_list})


def city(request, pid):
    """获取pid对应地区的下级地区"""
    # 1.获取pid对应地区的下级地区
    # area = models.areainfo.objects.filter(id=pid)
    # areas = area.areainfo_set.all()
    areas = models.areainfo.objects.filter(aparent__id=pid)
    # 2.变量areas拼接处json数据:atitle,id
    areas_list = []
    for area in areas:
        areas_list.append((area.id, area.atitle))
    return jsonresponse({'data': areas_list})

url

url(r'^prov', views.prov),  # 返回省级数据
url(r'^city(\d+)', views.city),  # 返回市级数据
url(r'^dis(\d+)', views.city),  # 返回县级数据

area.html

<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>省市县案例</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <script src="/static/js/jquery-3.3.1.js"></script>
    <script>
        $(function () {
            // 发起一个ajax请求/prov, 获取所有省级地区的信息
            // 获取信息,使用get;涉及到信息修改,使用post
            $.get('/prov', function (data) {
                // 回调函数
                // 获取返回的json数据
                let res = data.data;
                // 获取prov下拉列表框
                let prov = $('#prov');
                // 遍历res数组,获取每一个元素: [地区id,地区标题]
                for(let i=0; i<res.length; i++) {
                    let id = res[i][0];
                    let atitle = res[i][1];
                    let option_str = "<option value='"+ id +"'>" + atitle + "</option>";
                    // 向prov下拉列表框中追加元素
                    prov.append(option_str)
                }
            });

            // 绑定prov下拉框的change事件,获取省下面市的信息
            $('#prov').change(function () {
                let prov_id = $(this).val();
                $.get('/city'+prov_id, function (data) {
                    let res = data.data;
                    let city = $('#city');
                    city.empty().append('<option>---请选择市---</option>');
                    let dis = $('#dis');
                    dis.empty().append('<option>---请选择县---</option>');
                    $.each(res, function (index, item) {
                        let id = item[0];
                        let atitle = item[1];
                        let option_str = "<option value='"+ id +"'>" + atitle + "</option>";
                        // 向city下拉列表框中追加元素
                        city.append(option_str)
                    })
                })
            });

            // 绑定prov下拉框的change事件,获取省下面市的信息
            $('#city').change(function () {
                let city_id = $(this).val();
                $.get('/dis'+city_id, function (data) {
                    let res = data.data;
                    let dis = $('#dis');
                    dis.empty().append('<option>---请选择县---</option>');
                    $.each(res, function (index, item) {
                        let id = item[0];
                        let atitle = item[1];
                        let option_str = "<option value='"+ id +"'>" + atitle + "</option>";
                        // 向city下拉列表框中追加元素
                        dis.append(option_str)
                    })
                })
            });
        })
    </script>
</head>
<body>
<select id="prov">
    <option>---请选择省---</option>

</select>
<select id="city">
    <option>---请选择市---</option>
</select>
<select id="dis">
    <option>---请选择县---</option>
</select>
</body>
</html>