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。
原来的是这样的

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

1.8以后的变成这样的了。

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

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。

1class Province(models.Model):
2    name = models.CharField(max_length=30)
3 
4    def __str__(self):
5        return self.name
6 
7#城市表
8class City(models.Model):
9    name = models.CharField(max_length=40)
10    province = models.ForeignKey(Province)
11 
12    def __str__(self):
13        return self.name
14 
15#这个主要是用来显示,选择的结果
16class SelectP(models.Model):
17    province = models.ForeignKey(Province)
18    city = models.ForeignKey(City)

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

python manage.py migrate

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

1from django import forms
2from .models import SelectP
3 
4class SelectForm(forms.ModelForm):
5    class Meta:
6        model = SelectP
7        fields = '__all__'

五、后台
admin.py文件

1from .models import Province,City
2 
3# Register your models here.
4admin.site.register(Province)
5admin.site.register(City)

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

六、视图
views.py文件

1from django.shortcuts import render_to_response, get_object_or_404, redirect, urlresolvers, RequestContext
2from django.core import serializers
3from django.http import HttpResponse
4from .models import Province, SelectP
5from .forms import SelectForm
6# Create your views here.
7 
8#获取首页
9def index(request):
10    if request.method == 'POST':
11        form = SelectForm(request.POST)
12        if form.is_valid():
13            form.save()
14            return redirect(urlresolvers.reverse('select_index'))
15        else:
16            return HttpResponse('error')
17    else:
18        pro = Province.objects.all()
19        se = SelectP.objects.all()
20        return render_to_response('djmenu/index.html', {'province':pro,'select':se},
21                                  context_instance=RequestContext(request))
22 
23#ajax获取数据
24def getdata(request):
25    pk = request.GET['pk']
26    province = get_object_or_404(Province, pk=pk)
27    citys = province.city_set.all()
28    data = serializers.serialize('json', citys)
29    return HttpResponse(data, content_type='application/json')

七、配置url

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

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

1<!DOCTYPE html>
2<html lang="en">
3<head>
4    <meta charset="UTF-8">
5    <title>{% block title %}{% endblock %}</title>
7    <script src ="http://code.jquery.com/jquery-2.1.4.min.js"></script>
9    <script src="http://malsup.github.io/jquery.form.js"></script>
10</head>
11<body>
12    <form class="form-horizontal" action="{% url 'select_index' %}" method="post">
13    {% csrf_token %}
14        <div class="form-group">
15            <label for="id_province" class="control-label">选择省市</label>
16            <select class="form-control" id="id_province" name="province">
17                <option selected="selected">请选择</option>
18                {% for foo in province %}
19                    <option value="{{ foo.id }}">{{ foo.name }}</option>
20                {% endfor %}
21            </select>
22        </div>
23        <div class="form-group">
24            <label for="id_city" class="control-label">选择城市</label>
25            <select class="form-control" id="id_city" name="city">
26                    <option selected="selected">请选择</option>
27            </select>
28        </div>
29        <div class="form-group">
30            <input type="submit" value="提交">
31        </div>
32    </form>
33    <table class="table table-bordered">
34        <thead>
35            <tr>
36                <th>省</th>
37                <th>市</th>
38            </tr>
39        </thead>
40    <tbody>
41        {% for foo in select %}
42            <tr>
43            <td>{{ foo.province.name }}</td>
44            <td>{{ foo.city.name }}</td>
45            </tr>
46        {% endfor %}
47 
48    </tbody>
49    </table>
50    <script>
51        $('#id_province').change(function(){
52            var id = $('#id_province').val();
53            $.getJSON("{% url 'getdata' %}?pk="+id, function(data,textStatus){
54                var content='';
55                $.each(data, function(i, item){
56                       content+='<option value='+item.pk+'>'+item.fields.name+'</option>'
57                });
58                $('#id_city').html(content)
59            });
60        });
61    </script>
62 
63</body>
64</html>

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

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

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

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

十一、修改样式
将其中的

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

改成:

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

则样式会变成这样:

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

作者:蜗牛博客

暧昧帖

本文暂无标签

发表评论

*

*