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 :

 class Column(models.Model):
  name = models.CharField('栏目名称', max_length=256)
  slug = models.CharField('栏目网站', max_length=256, db_index=True)
  intro = models.TextField('栏目介绍', default='')

  def __str__(self):
    return self.name
 
  def get_absolute_url(self):
    return reverse('column', args=(self.slug, ))
 
  class Meta:
    verbose_name = '程序'
    verbose_name_plural = '程序'

    ordering = ['name']



class Article(models.Model):
  column = models.ManyToManyField(Column, verbose_name='ofpro')
  title = models.CharField('标题', max_length=256)
  pub_date = models.DateTimeField('发表时间', auto_now_add=True, editable=True)
  update_time = models.DateTimeField('更新时间', auto_now=True, null=True)
  slug = models.CharField('网站', max_length=256, db_index=True)
  author = models.ForeignKey('auth.User', blank=True, null=True, verbose_name='作者')
  published = models.BooleanField('最后发布', default=True)

  content = UEditorField('内容', height=300, width=1000, default=u'', blank=True, imagePath='uploads/images/',toolbars='besttome', filePath='uploads/files/')

  # UEditor是google的编辑器, 还没研究具体怎么用



  def __str__(self):
    return self.title 



  def get_absolute_url(self):
    return reverse('article', args=(self.slug, ))

 # reverse函数获取路径,在前端页面中调用get_absolute_url跳转到这个页面
  class Meta:

    verbose_name = '教程'
    verbose_name_plural = '教程'

数据库脚本文件 :

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

urls.py文件(部分) :

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

views.py文件 :

from django.shortcuts import render
from django.http import HttpResponse
from .models import Column, Article

def index(request):
  columns = Column.objects.all()
  return render(request, 'index.html', {'columns': columns})
# awm参数是从urls中传递过来的
def column_detail(request, awm):
  column= Column.objects.get(slug=awm)
  return render(request, 'news/column.html', {'column': column})

def article_detail(request, article_slug):
  #  article = Article.objects.get(slug=article_slug)[0]
  article = Article.objects.filter(slug=article_slug)[0]
  return render(request, 'news/article.html', {'article': article})

index模板文件 :

{% extends "base.html" %}
{% block title %} 首页 {% endblock title %}
{% block content %}

<ul>
  {% for column in columns %}
    <li>
      <a href="{{ column.get_absolute_url }}">{{ column.name }}</a>
    </li>
  {% endfor %}
</ul>
{% endblock content  %}

column模板文件 :

{% extends "base.html" %}
{% block title %}
{{ column.title }}
{% endblock title %}

{% block content %}
<p>栏目名称: {{ column.name }}</p>
栏目简介: {{ column.intro }}
栏目文章列表:
<ul>
  {% for article in column.article_set.all %}
    <li>
      <a  href="{{ article.get_absolute_url }}">
        {{ article.title }}
      </a>
    </li>
  {% endfor %}

</ul>
{% endblock content %}

article模板文件 :

{% extends "base.html" %}
{% block title %}
{{ article.title }}
{% endblock title %}

{% block content  %}
    <h1>文章标题: {{ article.title }}</h1>
    <div  id="main">
      {{ article.content }}
    </div>
{% endblock content %}
分析:
启动django后,当我输入http://IP:PORT时, 会进入url控制器, 显然http://IP:PORT符合url中的

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

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

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

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

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

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


index.html文件部分内容 :

{% for column in columns %}
    <li>
      <a href="{{ column.get_absolute_url }}">{{ column.name }}</a>
    </li>
  {% endfor %}

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

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

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

def get_absolute_url(self):
    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函数: 

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

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

<p>栏目名称: {{ column.name }}</p>
栏目简介: {{ column.intro }}
栏目文章列表:
<ul>
  {% for article in column.article_set.all %}
    <li>
      <a  href="{{ article.get_absolute_url }}">
        {{ article.title }} 
      </a>
    </li>
  {% endfor %}

</ul>
页面内容 :

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

>>> from news.models import Article, Column
>>> column = Column.objects.get(slug='sports')
>>> column
<Column: 体育新闻>
>>> column.article_set.all
<bound method BaseManager.all of <django.db.models.fields.related.create_many_related_manager.<locals>.ManyRelatedManager object at 0x7f91b517db38>>
>>> 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)...']
>>> column.article_set.all()[0].title  
'体育新闻_1'

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

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





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值