django入门:视图及模版

点击上方蓝字关注公众号

码个蛋第309次推文

前面讲了《环境及项目搭建》《数据模型》,这部分我们终于可以看到些真实的东西了,而不是数据...数据...数据...

创建 django 视图

普通视图

1.首先在应用文件夹下创建 urls.py 文件,用来配置视图的 url,然后我们需要在项目下的 urls.py 文件中将该应用的 urls 配置进去

# 在项目下 urls.py 文件配置应用的 urls.py 文件
from django.conf.urls import url, include
from django.contrib import admin

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    # include 作用:在 django 匹配 url 时候匹配完 blog/ 后,再次匹配下层地址,所以在 blog/ 
    # 后面不可以添加 "$" 符号,不然会导致不能匹配到地址,namespace 为了区分不同应用下同名的模版
    url(r'^blog/', include('blog.urls', namespace="blog")),
]

2.在应用文件夹下的 views.py 文件中加入视图

from django.http import HttpResponse

def index(request):
    return HttpResponse("Hello django")

3.在应用下的 urls.py 文件中将视图文件配置进去

from django.conf.urls import url
from . import views

# 加上 app_name, 值同 include 中 namespace 的值,否则可能会找不到 url
app_name = 'blog'
urlpatterns = [
 # 当模版引用本地 url 时候需要用到 name 字段值,例如
 # <a href="{% url 'blog:home' %}"><b>Home</b></a>
    url(r'^index$', views.home, name=home),
]

4.命令行将代码运行

python manage.py runserver 192.168.x.xxx:8080

然后可以通过网址 "http://192.168.x.xxx:8080/blog/index" 访问编写的界面

5.当 url 中带入参数进行传递时,例如

def hours_ahead(request, offset):
 try:
     offset = int(offset)
 except ValueError as e:
     print(e)
    dt = datetime.datetime.now() + datetime.timedelta(hours=offset)
    render(request, "time/ahead.html", locals())

在 url 配置的时候需要将 offset 传入

urlpatterns = [
 # ?P<offset> 为传递的参数字段名,紧随其后的是参数值的匹配正则
 # 可以通过 http://192.168.x.xxx:8080/time/ahead/(offset)/ 来访问相应网址
    url(r'^time/ahead/(?P<offset>\d{1, 2})/$', view.hours_ahead, name="time_ahead")
]

reverse() 在配置 url 时候的大用处

# 假设我们有个网址为 192.168.x.xxx:8080/post/1/ 其中 1 为 post 的 id 根据 id 不同显示不同 post
# 网址的正则为 url(r'post/(?P<pk>[0-9]+)/$', view.post, name="post_detail")
class Post(models.Model):
 title = models.CharField("标题", max_length=100)
 
 def get_post_url(self):
     # reverse 会自动指向 'blog:post_detail' 所指向的 url,kwargs 为传入的参数值
     return reverse('blog:post_detail', kwargs={'pk': self.pk})

Python 正则常用语法

使用模版创建视图

1.首先在项目根目录下创建 templates 文件夹,用来放视图模版,然后在项目下的 settings.py 文件中注册 templates 文件夹,使 django 能够在 templates 文件夹中找到相应的模版,在 TEMPLATES 中的 DIRS 列表中加入如下代码

'DIRS': [os.path.join(BASE_DIR, 'templates')],

2.在 templates 文件夹下再创建放应用模版的文件夹 例如 blog ,然后在 blog 创建 index.html 作为 index 视图的模版

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{{ title }}</title>
</head>
<body>
<h1>{{ welcome }}</h1>
</body>
</html>

3.修改视图文件函数

from django.shortcuts import render

def index(request):
 # context 中的参数名和模版中 {{ }} 包裹的相同
 return render(request, 'blog\index.html', context={
        'title': "My Blog Home",
        'welcome': "Welcome to My Blog"
 })
 
# 或者可以用以下方法来写
def index(request):
 title = "My Blog Home"
 welcome = "Welcome to My Blog"
 return render(request, 'blog\index.html', locals())

4.django 内置模版标签

  1. {% extends %} 继承模版标签

  2. 用两个大括号括起来的文字 (例如 {{ post_title }}) 称为变量 (variable),这意味着在此处插入指定变量的值

  3. {% if %}  [{% else %} 可省略]{% end if%} 标签

    1. {% if %} 标签接受 and, or 或者 not 关键字来对多个变量做判断,或者对变量取反 (not);

    2. 不允许在同一个标签中同时使用 and 和 or,但可以多次使用同一个逻辑操作符;

    3. 不支持用圆括号来组合比较操作;

    4. 没有 {% elif %} 标签,只能 {% if %} 嵌套达到效果;

    5. 一定要用 {% endif %} 关闭每一个 {% if %} 标签

    eg:

    {% if {{ str }} %}
        <p>Value is not null</p>
    {% else %}
        <p>Value is null</p>
    {% endif %}
  4. {% for %} [{% empty %} 可省略] {% endfor %} 标签

    1. 给标签增加一个 reversed 使得该列表被反向迭代  eg: {% for s in s_list reversed%}

    2. 可以嵌套使用 {% for %} 标签

    3. 执行循环之前通常先检测列表的大小,因此 for 标签支持一个可选的 {% empty %} 分句

    4. 不支持 break 和 continue,退出循环时候,可以改变正在迭代的变量,让其仅仅包含需要迭代的项目。

    5. 每个 {% for %} 循环里有一个称为 forloop 的模板变量,这个变量存在一些表示循环进度信息的属性,模板解析器碰到{% endfor %}标签后,forloop就不可访问了

      forloop.counter/counter0

      循环的执行次数的整数计数器,从1/0开始计数

      forloop.revcounter/revcounter0

      循环执行后的剩余项数量,首次执行为总数/总数减一,最后置为1/0

      forloop.first/last    首次/最后一次迭代为 True

      forloop.parentloop    当前循环的上一级循环的 forloop 对象的引用(嵌套循环情况下)

      eg:

      {% for country in countries %}
          <table>
          {% for city in country %}
              <tr>
              <td>Country {{ forloop.parentloop.counter }}</td>
              <td>City {{ forloop.counter }}</td>
              <td>{{ city }}</td>
              </tr>
          {% endfor %}
          </table>
      {% empty%}
          <p>There is no country</p>
      {% endfor %}

      {% ifequal/ifnotequal%} [{% else %}可省略]  {% endifqual/ifnotequal%} 标签

      比较两个变量的值并且显示一些结果,支持可选的 {% else%} 标签;只有模板变量,字符串,整数和小数可以作为 {% ifequal %} 标签的参数

  5. {% autoescape %}{% endautoescape %} 关闭代码块中的自动转义,父类已经关闭则子类也关闭

5.django 常用内置模版过滤器

模板过滤器是在变量被显示前修改它的值的一个简单方法,以 "|" 拼接,过滤器的参数跟随冒号之后并且总是以双引号包含,例如 {{ value|add:"2" }} 返回值为 value + 2 的值

add:"n",对象相加,如果是数字则是数字加法,列表则是列表的和,无法相加为空。

addslashes,增加反斜杠,处理 Javascript 文本非常有用

truncatewords:"n",显示变量前 n 个字符

pluralize:"y, ies",单词的复数形式,可以通过参数设置复数形式

date:"xxx",按指定的格式字符串参数格式化 date 或者 datetime 对象,例如 {{ pub| date:"F j, Y" }}  length,返回变量的长度;对于列表,返回列表元素的个数。对于字符串,返回字符串中字符的个数

safe,当系统设置 autoescaping 打开的时候,该过滤器使得输出不进行 escape 转换

striptags,删除 value 中的所有 HTML 标签

.......

6.django 自定义过滤器和标签

  1. 在应用目录下创建 templatetags 文件夹,同时建立空文件 __ init __.py 和过滤器文件 例如 custom_filter.py

  2. 在 custom_filter.py 文件中添加过滤器

from django import template
from blog.models import Category
# register 是 template.Library 的实例,是所有注册标签和过滤器的数据结构
register = template.Libary()

# 自定义过滤器
@register.filter
def get_value(dic, key_name):
 return dic.get(key_name)
 
@register.filter
def get_attr(d, m):
 if hasattr(d, m):
     return getattr(d, m)
    
# 自定义标签
@register.simple_tag
def get_all_category
 return Category.objects.all()

1.引用自定义过滤器时需要先导入再使用

{% load custom_filter %}
<html lang="en">
<body>
 <h1>{{ articles|get_value:"article"|get_attr:"id" }}</h1>
    {% get_all_category as category_list%}
    <ul>
        {% for category in category_list%}
         <li>
                <a href="#">{{ category.name }}</a>
         </li>
        {% empty %}
         There is no category!
        {% endfor%}
    </ul>
</body>
</html>

静态文件处理

  1. 在应用目录下创建 static 文件夹,可以将常用的 css 文件,js 文件等放入该文件夹

  2. 在需要引用静态文件的模版中做如下处理

{# 引入静态文件,只有加载标签模版后才能使用 {% static %} 标签 #}
{% load staticfiles %}
{# 在需要引入的地方引入相应文件,例如在 static 文件夹下有个 blog 文件夹,需要引用其 #}
{# 中的 css/bootstrap.min.css 文件可以通过如下方式进行引入 #}
<link rel="stylesheet" href="{% static 'blog/css/bootstrap.min.css' %}">

最后附上整个项目的地址:blog_project

https://github.com/kukyxs/blog_project

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值