django入门(四)通信录和导入导出

django入门(四)通信录和导入导出

阅读别人的中文笔记
http://www.woodpecker.org.cn/obp/django/django-stepbystep/newtest/doc/

step by step(七)
1.创建新的app
manage.py startapp address

2.修改address的models.py如下:
#coding=utf-8
from django.db import models

class Address(models.Model):
    name = models.CharField("姓名",max_length=32,unique=True)
    #gender 表示性别,它可以从一个 tuple 数据中进行选取。并且在后面的 radio_admin=True 表示在 admin 的  管理界面中将使用 radio 按钮来处理。
    gender = models.CharField("性别",choices=(("M","男"),("F","女")),max_length=1)
    telphone = models.CharField("电话",max_length=20)
    mobile = models.CharField("手机",max_length=11)
    room = models.CharField('房间', max_length=32)
    class Admin:
        pass
    def __str__(self):
        return self.name
3.修改settings.py导入address的模块和admin模块
INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    'django.contrib.admin',
    'easydjango.wiki',
    'easydjango.address',
)

4.生成address的表和导入admin
manage.py syncdb
报错如下:
TypeError: __init__() got an unexpected keyword argument 'radio_admin'
网上搜索了下,据说:
不能直接写在field里了,admin和model分离了,详见文档的自定义admin,那么我去掉radio_admin,创建成功:
D:\work\easydjango>manage.py syncdb
Creating table django_admin_log
Creating table address_address
Installing index for admin.LogEntry model

6.修改urls.py的定义
from django.conf.urls.defaults import *
# Uncomment the next two lines to enable the admin:
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
    # Example:
    # (r'^easydjango/', include('easydjango.foo.urls')),
    (r'^wiki/$', 'easydjango.wiki.views.index'),
    (r'^wiki/(?P<pagename>\w+)/$', 'easydjango.wiki.views.index'),
    (r'^wiki/(?P<pagename>\w+)/edit/$', 'easydjango.wiki.views.edit'),
    (r'^wiki/(?P<pagename>\w+)/save/$', 'easydjango.wiki.views.save'),
    (r'^address/', include('easydjango.address.urls')),
   
    # Uncomment the admin/doc line below and add 'django.contrib.admindocs'
    # to INSTALLED_APPS to enable admin documentation:
    # (r'^admin/doc/', include('django.contrib.admindocs.urls')),

    # Uncomment the next line to enable the admin:
    (r'^admin/', include(admin.site.urls)),
)
然后启动服务器 manage.py runserver后,访问地址http://localhost:8000/admin/。但是报错如下:
NameError at /admin/ name 'admin' is not defined
我的urls里面是:
(r'^admin/', include(admin.site.urls)),原来是只注意了下面,没有注意上面,几个import没有打开,改了就对了。有个哥号称做了版本的更新,这里记录下他的网址:http://quickbest.com.cn/discuz/thread-61139-1-1.html,我修改如下:
# Uncomment the next two lines to enable the admin:
from django.contrib import admin
admin.autodiscover()

7.增加超级用户
manage.py shell
>>> from django.contrib.auth.create_superuser import createsuperuser
报错如下:
>>> from django.contrib.auth.create_superuser import createsuperuser
Traceback (most recent call last):
  File "<console>", line 1, in <module>
ImportError: cannot import name createsuperuser
参考这篇文章http://docs.djangoproject.com/en/dev/topics/auth/,操作如下:
D:\work\easydjango>manage.py createsuperuser --username=sillycat [email protected]
Password:
Password (again):
Superuser created successfully.

修改了以上东东以后,只是能访问http://localhost:8000/admin,也可以用我们新增的用户名sillycat登陆上去了。

8.将address模块放到admin中管理
首先在address的app下新增这个文件admin.py,内容如下:
from django.contrib import admin
from easydjango.address.models import Address
admin.site.register(Address)

另外再address的models.py上增加
class Admin:
        pass

刷新后,就能出现address模块在http://localhost:8000/admin页面,并能够新增,修改等
里面列表显示的内容是model的类名,要重新model Address的toString方法,显示用户名更友好些:
def __str__(self):
        return self.name

9.修改表结构,在Address中增加room字段,修改models如下:
增加了room = models.CharField('房间', max_length=32)

修改表后重新刷新数据库:
D:\work\easydjango>manage.py reset address
You have requested a database reset.
This will IRREVERSIBLY DESTROY any data for
the "address" application in the database "./data.db".
Are you sure you want to do this?
Type 'yes' to continue, or 'no' to cancel: yes

10.修改了settings.py里面设置,可以让admin的相关页面变成中文:
TIME_ZONE = 'Asia/Shanghai'
LANGUAGE_CODE = 'zh-cn'

11.address的通用列表页面
Django 中的 view 相当于一个 Controller 的作用,它是用来收集数据,调用模板,真正的显示是在模板中处理的。使用 Controller 可能更合适,这样就称为 MTC 了。另外, Generic views 产生的意义在于 Django 的哲学理含 DRY (Don't repeat yourself, 不要自已重复),目的是重用,减少重复劳动。还有其它的哲学理含参见 Design philosophies 文档。
在address的app目录下新增urls.py文件,内容如下:
from django.conf.urls.defaults import *
from easydjango.address.models import Address

info_dict = {
    'queryset': Address.objects.all(),
}
urlpatterns = patterns('',
    (r'^/?$', 'django.views.generic.list_detail.object_list', info_dict),
)
其中的django.views.generic.list_detail.object_list就是所谓的通用views了。
其中的方法object_list() 需要的模板文件名为: app_label/model_name_list.html ,这是缺省要查找的模板名

12.在template中新增文件
template/address/address_list.html文件如下:
<h1>通讯录</h1>
<hr>
<table border="1">
<tr>
  <th>姓名</th>
  <th>性别</th>
  <th>电话</th>
  <th>手机</th>
  <th>房间</th>
</tr>
{% for person in object_list %}
<tr>
  <td>{{ person.name }}</td>
  <td>{{ person.gender }}</td>
  <td>{{ person.telphone }}</td>
  <td>{{ person.mobile }}</td>
  <td>{{ person.room }}</td>
</tr>
{% endfor %}
</table>

13.修改总的urls.py把address/urls.py包括进来
(r'^address/', include('easydjango.address.urls')),

哈哈,这样就可以
http://localhost:8000/admin 去CRUD操作address模块
http://localhost:8000/address去直接列表address模块          

step by step(八)
先做导入功能,导出功能参考前面章节的csv文件导出

1.下载示例中的data.csv文件
http://www.woodpecker.org.cn/obp/django/django-stepbystep/newtest/newtest/data.csv

2.修改template/address/address_list.html,加上导入的html内容
<form enctype="multipart/form-data" method="POST" action="/address/upload/">
上传通讯录文件: <input type="file" name="file"/><br/>
<input type="submit" value="上传文件"/>
</form>

3.修改address/views.py,在里面增加了upload方法
#coding=utf-8
from easydjango.address.models import Address
from django.http import HttpResponseRedirect
from django.shortcuts import render_to_response
from django.http import HttpResponse
from django.template import loader,Context

def upload(request):
    file_obj = request.FILES.get('file', None)
    if file_obj:
        import csv
        import StringIO
        #file_obj['content']已经玩不转了,django版本问题
        #buf = StringIO.StringIO(file_obj['content'])
        buf = StringIO.StringIO(file_obj.read())
        print file_obj.name
        try:
            reader = csv.reader(buf)
        except:
            return render_to_response('address/error.html',
                {'message':'你需要上传一个csv格式的文件!'})
        for row in reader:
            objs = Address.objects.filter(name=row[0])
            if not objs:
                obj = Address(name=row[0], gender=row[1],
                    telphone=row[2], mobile=row[3], room=row[4])
            else:
                obj = objs[0]
                obj.gender = row[1]
                obj.telphone = row[2]
                obj.mobile = row[3]
                obj.room = row[4]
            obj.save()
        return HttpResponseRedirect('/address/')
    else:
        return render_to_response('address/error.html',
            {'message':'你需要上传一个文件!'})
4.创建出错页面template/address/error.html,内容如下:
<h2>出错</h2>
<p>{{ message }}</p>
<hr>
<p><a href="/address/">返回</a></p>

5.修改address内部的urls.py
from django.conf.urls.defaults import *
from easydjango.address.models import Address
info_dict = {
    'queryset': Address.objects.all(),
}
urlpatterns = patterns('',
    (r'^/?$', 'django.views.generic.list_detail.object_list', info_dict),
    (r'^upload/$', 'address.views.upload'),
    (r'^output/$', 'address.views.output'),
)

启动服务manage.py runserver,访问http://localhost:8000/address,选择我们下载过来的data.csv文件,上传报错,报错如下:
TypeError at /address/upload/ 'InMemoryUploadedFile' object is unsubscriptable
也是因为版本问题吧,所以对views.py里面的代码做了修改
#原来的buf = StringIO.StringIO(file_obj['content']) 改为了
buf = StringIO.StringIO(file_obj.read())
上传导入成功了:)

然后做导出功能,参考原来的csv模块的操作
1.增加template/address/csv.html导出模版
{% for row in data %}{% for i in row %}"{{ i|addslashes }}",{% endfor %}
{% endfor %}

2.修改template/address/address_list.html增加导出的HTML片段
<hr>
<p><a href="/address/output/">导出为csv格式文件</a></p>

3.在address/views.py中加入导出的方法output
def output(request):
    response = HttpResponse(mimetype='text/csv')
    response['Content-Disposition'] = 'attachment; filename=%s' % 'address.csv'
    t = loader.get_template('address/csv.html')
    objs = Address.objects.all()
    d = []
    for o in objs:
        d.append((o.name, o.gender, o.telphone, o.mobile, o.room))
    c = Context({
        'data': d,
    })
    response.write(t.render(c))
    return response

4.修改address/urls.py的内部url映射
(r'^output/$', 'address.views.output'),

OK了,访问http://localhost:8000/address页面,里面的导出地方点击另存为,就能下载得到导出的csv文件了。

你可能感兴趣的:(thread,html,数据结构,django,mobile)