当前位置:   article > 正文

Django学习笔记(一)_

想搞清楚Django跟后台数据库是如何交互的。在网上找了好多,不是太麻烦就是觉得不靠谱,对我都不适合,找了好久,最后看到一个自强学堂的网站,很喜欢里面的内容。照着教程搭了一遍,还剩一些bug没解决。我想先弄清楚django跟后台怎么交互的再说,先分着说,然后最后总结一下吧。

使用得环境是Centos7+python3+django1.8。

1  virtaulenv

官方解释:virtualenv是一个创建隔离的python环境的一个工具,额。。。按照我现在的理解我是粗略得把它理解成windows里面的虚拟机。每个虚拟机都是一个单独的环境,与别得虚拟机没有关系。如果后续有更深得理解,再更。

2 安装和使用virtualenv

pip install virtualenv virtualwrapper

编辑root用户家目录下的.bash_profile文件(如果不是root用户,并且需要使用sudo命令的话,应在sudo的配置文件中加上此用户),加上:

export WORKON_HOME=$HOME/.virtualenvs

source /usr/python3/bin/virtualenvwrapper.sh

wirtualwrapper.sh脚本文件会帮我们在.virtualenvs目录下创建虚拟环境必要的文件和目录,然后就可以使用啦。

我使用到的命令:

mkvirtualenv mic:创建mic项目和运行环境mic

当退出虚拟环境后还想再次运行,workon mic即可

注:这个地方写virtualenvwrapper.sh的路径即可。如果你的linux系统中同时装了python2和python3,那么要在这个脚本文件中声      明python3的路径,就像这样
    export VIRTUALENVWRAPPER_PYTHON=/usr/python3/bin/python3;
    同时也要声明virtualenv在python3下的路径,就像这样

    export VIRTUALENVWRAPPER_VIRTUALENV=/usr/python3/bin/virtualenv

3 数据库的模板和脚本文件(列出主要的)

以下脚本文件内容来自于自强学堂。

数据库的模板文件在$YOUAPP_PATH/models.py :

  1. class Column(models.Model):
  2. name = models.CharField('栏目名称', max_length=256)
  3. slug = models.CharField('栏目网站', max_length=256, db_index=True)
  4. intro = models.TextField('栏目介绍', default='')
  5. def __str__(self):
  6. return self.name
  7. def get_absolute_url(self):
  8. return reverse('column', args=(self.slug, ))
  9. class Meta:
  10. verbose_name = '程序'
  11. verbose_name_plural = '程序'
  12. ordering = ['name']
  13. class Article(models.Model):
  14. column = models.ManyToManyField(Column, verbose_name='ofpro')
  15. title = models.CharField('标题', max_length=256)
  16. pub_date = models.DateTimeField('发表时间', auto_now_add=True, editable=True)
  17. update_time = models.DateTimeField('更新时间', auto_now=True, null=True)
  18. slug = models.CharField('网站', max_length=256, db_index=True)
  19. author = models.ForeignKey('auth.User', blank=True, null=True, verbose_name='作者')
  20. published = models.BooleanField('最后发布', default=True)
  21. content = UEditorField('内容', height=300, width=1000, default=u'', blank=True, imagePath='uploads/images/',toolbars='besttome', filePath='uploads/files/')
  22. # UEditor是google的编辑器, 还没研究具体怎么用
  23. def __str__(self):
  24. return self.title
  25. def get_absolute_url(self):
  26. return reverse('article', args=(self.slug, ))
  27. # reverse函数获取路径,在前端页面中调用get_absolute_url跳转到这个页面
  28. class Meta:
  29. verbose_name = '教程'
  30. verbose_name_plural = '教程'

数据库脚本文件 :

  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. # @Date : 2015-07-28 20:38:38
  4. # @Author : Weizhong Tu (mail@tuweizhong.com)
  5. # @Link : http://www.tuweizhong.com
  6. '''
  7. create some records for demo database
  8. '''
  9. from minicms.wsgi import *
  10. from news.models import Column, Article
  11. def main():
  12. columns_urls = [
  13. ('体育新闻', 'sports'),
  14. ('社会新闻', 'society'),
  15. ('科技新闻', 'tech'),
  16. ]
  17. for column_name, url in columns_urls:
  18. c = Column.objects.get_or_create(name=column_name, slug=url)[0]
  19. # 创建 10 篇新闻
  20. for i in range(1, 11):
  21. article = Article.objects.get_or_create(
  22. title='{}_{}'.format(column_name, i),
  23. slug='article_{}'.format(i),
  24. content='新闻详细内容: {} {}'.format(column_name, i)
  25. )[0]
  26. article.column.add(c)
  27. if __name__ == '__main__':
  28. main()
  29. print("Done!")

urls.py文件(部分) :

  1. urlpatterns = [
  2. url(r'^admin/', include(admin.site.urls)),
  3. url(r'^ueditor/', include(DjangoUeditor_urls)),
  4. url(r'^$', 'news.views.index', name='index'),
  5. # name是正则表达式的别名,在.html文件中使用这个>匹配条件时,
  6. # 只用写上index,即使正则表达式匹配规则更改也没>关系。
  7. url(r'^column/(?P<awm>[^/]+)/$', 'news.views.column_detail', name='column'),
  8. # ?P<awm>这个awm相当于一个变量,[^/]不匹配/,+匹配前面的正则一次或多次,
  9. # http://192.168.80.126:8080/column/tech/a/ : tech就是这个awm变量的值,
  10. # 由于后面有不匹配tech后的/, 因此后面的a参数不被匹配,就报错.
  11. # 这个变量是在views中传递给函数的,因此在返回给 户端后,可以在页面打印出来.
  12. url(r'^news/(?P<article_slug>[^/]+)/$', 'news.views.article_detail', name='article'),
  13. ]

views.py文件 :

  1. from django.shortcuts import render
  2. from django.http import HttpResponse
  3. from .models import Column, Article
  4. def index(request):
  5. columns = Column.objects.all()
  6. return render(request, 'index.html', {'columns': columns})
  7. # awm参数是从urls中传递过来的
  8. def column_detail(request, awm):
  9. column= Column.objects.get(slug=awm)
  10. return render(request, 'news/column.html', {'column': column})
  11. def article_detail(request, article_slug):
  12. # article = Article.objects.get(slug=article_slug)[0]
  13. article = Article.objects.filter(slug=article_slug)[0]
  14. return render(request, 'news/article.html', {'article': article})

index模板文件 :

  1. {% extends "base.html" %}
  2. {% block title %} 首页 {% endblock title %}
  3. {% block content %}
  4. <ul>
  5. {% for column in columns %}
  6. <li>
  7. <a href="{{ column.get_absolute_url }}">{{ column.name }}</a>
  8. </li>
  9. {% endfor %}
  10. </ul>
  11. {% endblock content %}

column模板文件 :

  1. {% extends "base.html" %}
  2. {% block title %}
  3. {{ column.title }}
  4. {% endblock title %}
  5. {% block content %}
  6. <p>栏目名称: {{ column.name }}</p>
  7. 栏目简介: {{ column.intro }}
  8. 栏目文章列表:
  9. <ul>
  10. {% for article in column.article_set.all %}
  11. <li>
  12. <a href="{{ article.get_absolute_url }}">
  13. {{ article.title }}
  14. </a>
  15. </li>
  16. {% endfor %}
  17. </ul>
  18. {% endblock content %}

article模板文件 :

  1. {% extends "base.html" %}
  2. {% block title %}
  3. {{ article.title }}
  4. {% endblock title %}
  5. {% block content %}
  6.     <h1>文章标题: {{ article.title }}</h1>
  7.     <div id="main">
  8.      {{ article.content }}
  9.     </div>
  10. {% endblock content %}
分析:
启动django后,当我输入http://IP:PORT时, 会进入url控制器, 显然http://IP:PORT符合url中的

url(r'^$', 'news.views.index', name='index')这条规则, 此时django会去news(app名)下的views(视图)文件中的index函数。

下面的代码是视图中的index函数的部分 :

  1. def index(request):
  2. columns = Column.objects.all()
  3. return render(request, 'index.html', {'columns': columns})

不清楚Column.objects.all()的值 :

  1. 打开python3 manage.py shell
  2. >>> from .models import Column, Article
  3. >>> columns = Column.objests.all()
  4. >>> columns
  5. [<Column: 体育新闻>, <Column: 社会新闻>, <Column: 科技新闻>]

index函数返回被渲染后的index.html文件, 然后就是打开网页看到的内容 :


index.html文件部分内容 :

  1. {% for column in columns %}
  2. <li>
  3. <a href="{{ column.get_absolute_url }}">{{ column.name }}</a>
  4. </li>
  5. {% endfor %}

网页显示column.name,column.name是之前插入的column_name, 也就是体育新闻,社会新闻,科技新闻三个字段.

  1. 数据库脚本文件部分
  2. columns_urls = [
  3. ('体育新闻', 'sports'),
  4. ('社会新闻', 'society'),
  5. ('科技新闻', 'tech'),
  6. ]
  7. for column_name, url in columns_urls:
  8. c = Column.objects.get_or_create(name=column_name, slug=url)[0]

然后在index.html文件中可以看到, 这三个字段分别连接到get_absolute_url这个函数的返回值中, 于是去models.py文件中(模型)中找到这个函数:

  1. def get_absolute_url(self):
  2.     return reverse('column', args=(self.slug, ))

这个返回值是/column/SLUG, 这里的SLUG也就是前面数据库脚本文件中的url变量的值, 由数据库脚本看出体育新闻对应的SLUG是sports, 社会新闻对应的SLUG是soceity, 科技新闻对应的SLUG是tech, 即当我点击体育新闻时, 会请求/column/sports页面.  这一步完成了前端到后台数据库取数的步骤. url控制器会查看url模式, 发现匹配 :

 url(r'^column/(?P<awm>[^/]+)/$', 'news.views.column_detail', name='column'),

于是去视图中找column_detail函数: 

  1. def column_detail(request, awm):
  2. column= Column.objects.get(slug=awm)
  3. return render(request, 'news/column.html', {'column': column}

于是找到模板目录的news下的column.html :

  1. <p>栏目名称: {{ column.name }}</p>
  2. 栏目简介: {{ column.intro }}
  3. 栏目文章列表:
  4. <ul>
  5. {% for article in column.article_set.all %}
  6. <li>
  7. <a href="{{ article.get_absolute_url }}">
  8. {{ article.title }}
  9. </a>
  10. </li>
  11. {% endfor %}
  12. </ul>
页面内容 :

不是很清楚column.article_set.all和 article.title的值,打开shell, 可以看到column.article_set.all的值 :

  1. >>> from news.models import Article, Column
  2. >>> column = Column.objects.get(slug='sports')
  3. >>> column
  4. <Column: 体育新闻>
  5. >>> column.article_set.all
  6. <bound method BaseManager.all of <django.db.models.fields.related.create_many_related_manager.<locals>.ManyRelatedManager object at 0x7f91b517db38>>
  7. >>> column.article_set.all()[<Article: 体育新闻_1>, <Article: 体育新闻_2>, <Article: 体育新闻_3>, <Article: 体育新闻_4>, <Article: 体育新闻_5>, <Article: 体育新闻_6>, <Article: 体育新闻_7>, <Article: 体育新闻_8>, <Article: 体育新闻_9>, <Article: 体育新闻_10>, <Article: 体育新闻_1>, <Article: 体育新闻_2>, <Article: 体育新闻_3>, <Article: 体育新闻_4>, <Article: 体育新闻_5>, <Article: 体育新闻_6>, <Article: 体育新闻_7>, <Article: 体育新闻_8>, <Article: 体育新闻_9>, <Article: 体育新闻_10>, '...(remaining elements truncated)...']
  8. >>> column.article_set.all()[0].title
  9. '体育新闻_1'

也就是上图中看到的体育新闻1-10.

总结: django大致的工作流程是: 当有请求到达时, 先去url控制器查找匹配规则, 匹配成功去view视图中找到相应的方法(函数), 然后去对应的模板目录找到html文件, 在html中获取models(模型)中相应的变量值, 然后将结果返回给客户端. 数据库脚本文件中涉及到数据库表的多对多关系, 没有做说明, 文中一些bug也没说明.





声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/黑客灵魂/article/detail/799799
推荐阅读
相关标签