Home >  > Django实战项目四: 二级城市联动

Django实战项目四: 二级城市联动

0

环境:
Python 3.6.4
Django 1.8.2

用上面的环境遭遇了以下两项错误:

1.AttributeError: module 'html.parser' has no attribute 'HTMLParseError'
这是因为HTMLParseError在pythons3.5已经没有了,需要将python版本回退到3.3或3.4。

2.str' object has no attribute 'resolve
这是因为django1.8以上的版本,在配置urls.py文件时,使用的是正则表达式替换原来的patterns。
原来的是这样的

urlpatterns = patterns('',
(r'^$', direct_to_template, {'template' : 'a.html'}),
# ...

1.8以后的变成这样的了。

urlpatterns = [
    (r'^$', direct_to_template, {'template' : 'a.html'}),
    ...
]

3.django 1.7使用的是def __str__(self),如果是使用def __unicode__(self)的,还要退回以前更低的版本。

所以将环境退回:

Python 3.4
django 1.7.2

一、虚拟环境

在Anaconda的base环境下,执行conda create -n xx命令建立的虚拟环境。然后使用命令激活它。使用pip命令安装Django。

conda create -n select python=3.4
conda activate select
pip install -i https://pypi.douban.com/simple/ Django==1.7.2

二、创建项目及应用
django-admin startproject ajaxselect
cd ajaxselect
python manage.py startapp djmenu
并将djmenu添加到setting.py的INSTALLED_APPS里面。

三、数据库
修改djmenu/models.py,加入models。

class Province(models.Model):
    name = models.CharField(max_length=30)

    def __str__(self):
        return self.name

#城市表
class City(models.Model):
    name = models.CharField(max_length=40)
    province = models.ForeignKey(Province)

    def __str__(self):
        return self.name

#这个主要是用来显示,选择的结果
class SelectP(models.Model):
    province = models.ForeignKey(Province)
    city = models.ForeignKey(City)

并通过以下两条命令生成数据库。
python manage.py makemigrations polls

python manage.py migrate

四、forms.py
在models.py的同级目录,建立forms.py文件,内容如下:

from django import forms
from .models import SelectP

class SelectForm(forms.ModelForm):
    class Meta:
        model = SelectP
        fields = '__all__'

五、后台
admin.py文件

from .models import Province,City

# Register your models here.
admin.site.register(Province)
admin.site.register(City)

再使用python manage.py createsuperuser设定后台的账号,密码,再运行python manage.py runserver

六、视图
views.py文件

from django.shortcuts import render_to_response, get_object_or_404, redirect, urlresolvers, RequestContext
from django.core import serializers
from django.http import HttpResponse
from .models import Province, SelectP
from .forms import SelectForm
# Create your views here.

#获取首页
def index(request):
    if request.method == 'POST':
        form = SelectForm(request.POST)
        if form.is_valid():
            form.save()
            return redirect(urlresolvers.reverse('select_index'))
        else:
            return HttpResponse('error')
    else:
        pro = Province.objects.all()
        se = SelectP.objects.all()
        return render_to_response('djmenu/index.html', {'province':pro,'select':se},
                                  context_instance=RequestContext(request))

#ajax获取数据
def getdata(request):
    pk = request.GET['pk']
    province = get_object_or_404(Province, pk=pk)
    citys = province.city_set.all()
    data = serializers.serialize('json', citys)
    return HttpResponse(data, content_type='application/json')

七、配置url

urlpatterns = patterns('djmenu.views',    
    url(r'^index/$', 'index', name='select_index'),
    url(r'^getdata/$', 'getdata', name='getdata'),
    url(r'^admin/', include(admin.site.urls))
)

八、模板
创建djmenu/templates/djmenu/目录,在该目录下创建index.html。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{% block title %}{% endblock %}</title>
    <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/4.1.1/css/bootstrap.min.css">
    <script src ="http://code.jquery.com/jquery-2.1.4.min.js"></script>
    <script src = "https://cdn.bootcss.com/bootstrap/4.1.1/js/bootstrap.min.js"></script>
    <script src="http://malsup.github.io/jquery.form.js"></script>
</head>
<body>
    <form class="form-horizontal" action="{% url 'select_index' %}" method="post">
    {% csrf_token %}
        <div class="form-group">
            <label for="id_province" class="control-label">选择省市</label>
            <select class="form-control" id="id_province" name="province">
                <option selected="selected">请选择</option>
                {% for foo in province %}
                    <option value="{{ foo.id }}">{{ foo.name }}</option>
                {% endfor %}
            </select>
        </div>
        <div class="form-group">
            <label for="id_city" class="control-label">选择城市</label>
            <select class="form-control" id="id_city" name="city">
                    <option selected="selected">请选择</option>
            </select>
        </div>
        <div class="form-group">
            <input type="submit" value="提交">
        </div>
    </form>
    <table class="table table-bordered">
        <thead>
            <tr>
                <th>省</th>
                <th>市</th>
            </tr>
        </thead>
    <tbody>
        {% for foo in select %}
            <tr>
            <td>{{ foo.province.name }}</td>
            <td>{{ foo.city.name }}</td>
            </tr>
        {% endfor %}

    </tbody>
    </table>
    <script>
        $('#id_province').change(function(){
            var id = $('#id_province').val();
            $.getJSON("{% url 'getdata' %}?pk="+id, function(data,textStatus){
                var content='';
                $.each(data, function(i, item){
                       content+='<option value='+item.pk+'>'+item.fields.name+'</option>'
                });
                $('#id_city').html(content)
            });
        });
    </script>

</body>
</html>

在这里,使用{% url 'select_index' %}这样的形式,其实select_index就是对应urls.py中的index/这个url的名称。

九、添加数据
进入后台,添加相关省份、城市的数据。

十、成果展示
上方选择省份、城市之后,点击“提交”按钮,就可以看到刚刚选择的城市出现在最下方。

进入数据库,可以看到保存的选择信息。

十一、修改样式
将其中的

 <form class="form-horizontal" action="{% url 'select_index' %}" method="post">

改成:

<form class="form-inline" action="{% url 'select_index' %}" method="post">

则样式会变成这样:

后记:本来打算1小时弄完的东西,到最后完工花了差不多4小时,时间管理啊!

作者:蜗牛博客

暧昧帖

本文暂无标签

发表评论

*

*