django学后笔记

目录

django

0.命令整理

1. 环境搭建

2.first project

2.1 hello,world

2.2 home.html

3. 模型设计

3.1 博客板块设计

3.2 代码实现

3.3 试验models API

3.3.1python指令创建对象

3.3.2 模型管理器创建对象

4.视图函数

5.搜索引擎设置

6. 模板

7. 表单

7.1 前言

7.2 Forms API

7.3 用BootStarp表单渲染

py文件详解

1.settings.py

1.1静态文件

1.2 INSTALLED_APPS

1.3 X_FRAME_OPTIONS

2.urls.py

3. models.py

4. urls.py

常用函数


django

django学习笔记

0.命令整理

  • 安装django

    pip install django==#version#
  • 创建项目

    cd Django
    django-admin startproject #项目名# 
  • 创建app

    app是功能模块

    python manage.py startapp #app名#
  • 运行项目

    python manage.py runserver
  • 停止项目

    ctrl + c
  • 退出虚拟环境

    deactivate
  • 迁移模型

    boards/migrations ⽬录创建了⼀个名为0001_initial.py 的⽂件。它代表了应⽤程序模型的当前状态。在下⼀步,Django将使⽤该⽂件创建表和列。

    python manage.py makemigrations

    将生成的文件应用到数据库

    python manage.py migrate
  • python shell

    python

    启动了一个普通的 Python 解释器会话,可以执行任意的 Python 代码,但不会自动加载 Django 项目的设置和配置。

    python manage.py shell

    启动了一个特殊的 Django 交互式 shell。它会加载当前 Django 项目的设置和配置,使得你可以直接在 shell 中与 Django 项目进行交互。在这个 shell 中,你可以导入和使用 Django 的模型、管理器和其他 Django 特定的功能,而无需手动设置 Django 环境。

  • 退出交互式控制台

    exit()
  • 创建超级管理员

python manage.py createsuperuser

1. 环境搭建

2.first project

2.1 hello,world

创建app borads

borads/views.py

from django.http import HttpResponse
def home(request):
    return HttpResponse('Hello, World!')

我们定义了一个视图home,home接收request并将字符串‘hello ,world’作为参数返回

而django将在url.py中调用视图home

board/urls.py

from django.conf.urls import url
from django.contrib import admin

from boards import views

urlpatterns = [
    re_path(r'^$', views.home, name='home'),
    re_path(r'^admin/', admin.site.urls),
]

re_path(r'^$', views.home, name='home') 的作用是:

  • 通过正则表达式定义一个字符串用于匹配网站的url路径。

    使用了正则表达式:re_path, 未使用正则表达式:path, 老版本django使用:url

  • 网页访问了该路径则将请求交给 views.home 视图函数处理。

  • 为这个 URL 模式指定一个名称 home,方便在其他地方引用。

    这个名称可以在项目的其他地方使用,例如在模板中使用 {% url 'home' %} 来生成这个 URL,或者在视图函数中使用 reverse('home') 来反向解析这个 URL。命名 URL 的好处是,即使 URL 模式发生变化,只要名称不变,其他地方的代码就不需要修改。

2.2 home.html

home.html

<!DOCTYPE html>
<html>
<head>
    <title>Home</title>
</head>
<body>
    <h1>Boards</h1>
    <ul>
        {% for board in boards %}
            <li>{{ board.name }} - {{ board.description }}</li>
        {% endfor %}
    </ul>
</body>
</html>

boards/view.py

def Home(request):
    boards = Board.objects.all()
    return render(request, 'home.html', {'boards': boards})

render是 Django 视图函数中用于返回渲染后的 HTML 页面的常用方法。它的作用是将数据{'boards': boards}传递给页面'home.html'中的模板,并生成一个 HTTP 响应,将页面返回给客户端。

  1. request: 这是 HTTP 请求对象,包含了客户端发送的请求信息。

  2. 'home.html': 这是页面的名称,Django 会根据这个名称在配置的模板目录中查找并渲染这个模板文件。

  3. {'boards': boards}: 这是一个字典,包含了要传递给模板的数据。在这个例子中,boards 是一个包含 Board 对象的查询集(QuerySet),它将被传递给模板,并在模板中通过变量名 boards 访问。

3. 模型设计

3.1 博客板块设计

Web Board类图

  • Board:版块

  • Topic:主题

  • Post:帖⼦(译注:其实就是主题的回复或评论)

image-20240706190047116

在⼀个主题(Topic)中,我们需要有⼀个字段(译注:其实就是通过外键来关联)来确定它属于哪个版块(Board)。

同样,帖⼦(Post)也需要⼀个字段来表示它属于哪个主题,这样我们就可以列出在特定主题内创建的帖⼦。

最后,我们需要⼀个字段来表示主题是谁发起的,帖⼦是谁发的

详细设计

Board 模型包括两个字段

  • name字段必须是唯⼀的,为了避免有重复的名称

  • description ⽤于说明这个版块是做什么⽤的。

Topic 模型包括四个字段:

  • subject 表示主题内容

  • last_update ⽤来定义话题的排序

  • starter ⽤来识别谁发起的话题

  • board ⽤于指定它属于哪个版块。

Post 模型有⼀个

  • message 字段,⽤于存储回复的内容

  • created_at 在排序时候⽤(最先发表的帖⼦排最前⾯)

  • updated_at 告诉⽤户是否更新了内容

  • 同时,还需要有对应的 User 模型的引⽤

  • Post 由谁创建的和谁更新的。

最后是 User 模型。在类图中,我只提到了字段 username,password,

email, is_superuser 标志,因为这⼏乎是我们现在要使⽤的所有东⻄。

需要注意的是,我们不需要创建 User 模型,因为Django已经在contrib包中

内置了User模型,我们将直接拿来⽤。

3.2 代码实现

boards/models.py

from django.db import models
from django.contrib.auth.models import User

class Board(models.Model):
	name = models.CharField(max_length=30, unique=True)
	description = models.CharField(max_length=100)
    
class Topic(models.Model):
	subject = models.CharField(max_length=255)
	last_updated = models.DateTimeField(auto_now_add=True)
	board = models.ForeignKey(Board, related_name='topics')
	starter = models.ForeignKey(User, related_name='topics')
    
class Post(models.Model):
	message = models.TextField(max_length=4000)
	topic = models.ForeignKey(Topic, related_name='posts')
	created_at = models.DateTimeField(auto_now_add=True)
	updated_at = models.DateTimeField(null=True)
	created_by = models.ForeignKey(User, related_name='posts')
	updated_by = models.ForeignKey(User, null=True, related_name='+')

Board模型

  • name: 一个长度不超过30个字符的字符串字段,且必须是唯一的。

  • description: 一个长度不超过100个字符的字符串字段。

Topic模型

  • subject: 一个长度不超过255个字符的字符串字段。

  • last_updated: 一个日期时间字段,当 Topic 对象创建时自动设置为当前时间。

  • board: 一个外键字段,关联到 Board 模型,使用 related_name='topics',当 Board 被删除时,相关的 Topic 也会被删除。

  • starter: 一个外键字段,关联到 User 模型,使用 related_name='topics',当 User 被删除时,相关的 Topic 也会被删除。

  • views: 一个正整数字段,默认值为0,用于记录 Topic 的浏览次数

Post模型

  • message: 一个长度不超过4000个字符的文本字段。

  • topic: 一个外键字段,关联到 Topic 模型,使用 related_name='posts',当 Topic 被删除时,相关的 Post 也会被删除。

  • created_at: 一个日期时间字段,当 Post 对象创建时自动设置为当前时间。

  • updated_at: 一个日期时间字段,可以为空,用于记录 Post 的更新时间。

  • created_by: 一个外键字段,关联到 User 模型,使用 related_name='posts',当 User 被删除时,相关的 Post 也会被删除。

  • updated_by: 一个外键字段,关联到 User 模型,可以为空,使用 related_name='+',当 User 被删除时,相关的 Post 也会被删除。

Board 模型代表论坛的板块,包含名称和描述,并提供了获取相关帖子数量和最后一个帖子的方法。

Topic 模型代表论坛的主题,包含主题名称、最后更新时间、所属板块、发起用户和浏览次数。

Post 模型代表论坛的帖子,包含消息内容、所属主题、创建时间和更新时间、创建用户和更新用户。

对应的mysql创建表语句

CREATE TABLE `board` (
    `id` INT AUTO_INCREMENT PRIMARY KEY,
    `name` VARCHAR(30) UNIQUE NOT NULL,
    `description` VARCHAR(100) NOT NULL
);

CREATE TABLE `topic` (
    `id` INT AUTO_INCREMENT PRIMARY KEY,
    `subject` VARCHAR(255) NOT NULL,
    `last_updated` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `board_id` INT NOT NULL,
    `starter_id` INT NOT NULL,
    `views` INT UNSIGNED NOT NULL DEFAULT 0,
    FOREIGN KEY (`board_id`) REFERENCES `board`(`id`) ON DELETE CASCADE,
    FOREIGN KEY (`starter_id`) REFERENCES `auth_user`(`id`) ON DELETE CASCADE
);

CREATE TABLE `post` (
    `id` INT AUTO_INCREMENT PRIMARY KEY,
    `message` TEXT NOT NULL,
    `topic_id` INT NOT NULL,
    `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `updated_at` DATETIME,
    `created_by_id` INT NOT NULL,
    `updated_by_id` INT,
    FOREIGN KEY (`topic_id`) REFERENCES `topic`(`id`) ON DELETE CASCADE,
    FOREIGN KEY (`created_by_id`) REFERENCES `auth_user`(`id`) ON DELETE CASCADE,
    FOREIGN KEY (`updated_by_id`) REFERENCES `auth_user`(`id`) ON DELETE CASCADE
);

related_name 是一个用于反向查询的属性。当你在一个模型中定义一个外键(ForeignKey)或一个多对多关系(ManyToManyField)时,Django 会自动创建一个反向关系,允许你从相关模型访问这个模型。related_name 允许你为这个反向关系指定一个自定义的名称。

  • 获取一个 Topic 实例

topic = Topic.objects.get(id=1)

  • 使用默认的反向关系名称 (post_set

posts_default = topic.post_set.all()
  • 使用自定义的反向关系名称

posts_custom = topic.posts.all() #获取与该 Topic 相关的所有 Post 对象

在⼀个 HTML 模板⽂件⾥⾯,我们不使⽤括号,就只是 board.topics.all

过滤一些数据还可以

board.topics.filter(subject__contains='Hello')

3.3 试验models API

3.3.1python指令创建对象

启动python shell

导入Board类

from boards.models import Board

创建新的board对象

board = Board(name='Django', description='This is a board about Django.')

将对象保存到数据库中

board.save()
3.3.2 模型管理器创建对象

通过django自带属性objects访问模型管理器

board = Board.objects.create(name='Python', description='General discussion about Python.')

也可通过objects列出数据库中所有现有板块

Board.objects.all()

还可以查询数据库并返回单个对象

board = Board.objects.get(id=1)
board.name
'Django'

查询不存在的对象会引发异常

get方法的参数可以是模型的任何字段。查询非唯一标识对象会返回多个对象,也会引发异常。

4.视图函数

5.搜索引擎设置

在manage.py所在的⽬录创建⼀个名为 templates的新⽂件夹:

myproject/

|-- myproject/

| |-- boards/

| |-- myproject/

| |-- templates/ <-- 这⾥

| +-- manage.py

+-- venv/

在templates⽂件夹中,创建⼀个名为home.html的HTML⽂件:

templates/home.html

未完待续

6. 模板

7. 表单

7.1 前言

csrf_token 的模板标签:

{% csrf_token %}

Django 使⽤ CSRF Token(Cross-Site Request Forgery Token) 保护所有的POST 请求。

检索数据

<input type="text" id="id_subject" name="subject">
<input type="text" id="id_message" name="message">
subject = request.POST['subject']
message = request.POST['message']

具体实现

from django.contrib.auth.models import User
from django.shortcuts import render, redirect, get_object_or_404
from .models import Board, Topic, Post
def new_topic(request, pk):
    board = get_object_or_404(Board, pk=pk)
    if request.method == 'POST':
        subject = request.POST['subject']
        message = request.POST['message']
        user = User.objects.first() # TODO: 临时使⽤⼀个账号作为
        登录⽤户
        topic = Topic.objects.create(
            subject=subject,
            board=board,
            starter=user
        )
        post = Post.objects.create(
            message=message,
            topic=topic,
            created_by=user
        )
        return redirect('board_topics', pk=board.pk) 
      
    return render(request, 'new_topic.html', {'board': board}
)

7.2 Forms API

Forms API 可在模块 django.forms 中得到。

Django 使⽤两种类型的form: forms.Form 和 forms.ModelForm 。

Form 类是通⽤的表单实现。我们可以使⽤它来处理与应⽤程序 model 没有直接关联的数据。

ModelForm 是 Form 的⼦类,它与 model 类相关联。

Boards/forms.py

from django import forms
from .models import Topic

class NewTopicForm(forms.ModelForm):
    message = forms.CharField(widget=forms.Textarea(), max_length=4000)
    #Django Forms API 提供了强大的表单验证功能。表单字段可以定义各种验证规则,如必填字段、最大长度、正则表达式等。
    #form.is_valid() 方法会自动检查表单数据是否符合这些规则。
    
    class Meta:
        model = Topic #表单关联的模型是 Topic
        fields = ['subject', 'message'] #表单包含的字段是 subject 和 message。

Boards/views.py #未使用forms

def new_topic(request, pk):
    board = get_object_or_404(Board, pk=pk)
    if request.method == 'POST':
        subject = request.POST['subject']
        message = request.POST['message']
        user = User.objects.first()
        topic = Topic.objects.create(
            subject=subject,
            board=board,
            starter=user
        )
        post = Post.objects.create(
            message=message,
            topic=topic,
            created_by=user
        )
        return redirect('board_topics', pk=board.pk)
    return render(request, 'new_topic.html', {'board': board})

Borads/views.py #使用forms

def new_topic(request, pk):
    board = get_object_or_404(Board, pk=pk) #获取 Board 对象。如果 Board 对象不存在,则返回 404 错误。
    user = User.objects.first()  # TODO: get the currently logged in user
    if request.method == 'POST': #如果是 POST 请求,表示用户提交了表单数据。
        form = NewTopicForm(request.POST)#创建 NewTopicForm 表单实例,并将请求中的 POST 数据传递给它。
        if form.is_valid(): #调用 form.is_valid() 验证表单数据是否有效。
            topic = form.save(commit=False) #调用 form.save创建 Topic 对象,但不保存到数据库。
            topic.board = board
            topic.starter = user
            topic.save()
            post = Post.objects.create(
                message=form.cleaned_data.get('message'),
                topic=topic,
                created_by=user
            )
            return redirect('board_topics', pk=board.pk) # TODO: redirect to the created topic page
    else:
        form = NewTopicForm() #如果请求方法不是 POST,则创建一个空的 NewTopicForm 表单实例。
    return render(request, 'new_topic.html', {'board': board,'form': form})

核心

if request.method == 'POST':
    form = NewTopicForm(request.POST)
    if form.is_valid():
        topic = form.save()
        return redirect('board_topics', pk=board.pk)
else:
	form = NewTopicForm()
return render(request, 'new_topic.html', {'form': form})	

new_topic.html

<form method="post">
    {% csrf_token %}
    {{ form.as_p }}
	<button type="submit" class="btn btn-success">Post</button>
</form>

form 有三个渲染选项: form.as_table , form.as_ul 和form.as_p 。

这是⼀个快速的渲染表单所有字段的⽅法。顾名思义, as_table 使⽤ table 标签来格式化输⼊, as_ul 使⽤ li 标签。

image-20240707182923486

7.3 用BootStarp表单渲染

待定

py文件详解

1.settings.py

1.1静态文件

STATICFILES_DIRS用于指定静态文件查找目录

在项目根目录下创建static文件夹

settings.py

STATIC_URL = 'static/'
STATICFILES_DIRS = [
    BASE_DIR / 'static'
]

python3.4以上版本推荐使用BASE_DIR / 'static'

较早版本会使用os.path.join(BASE_DIR, 'static')

功能等价

模板的开头引用标签 { % load static % }

1.2 INSTALLED_APPS

1.3 X_FRAME_OPTIONS

用于响应头x_frame_options

通过指定是否允许网页被嵌入到<frame><iframe><object>中,用于防止点击劫持攻击.

常见的值有:

  • DENY:表示该页面不允许被任何页面嵌入。

  • SAMEORIGIN:表示该页面只能被同源的页面嵌入。

  • ALLOW-FROM uri:表示该页面只能被指定的URI嵌入(不常用)

2.urls.py

re_path(regex, view, kwargs=None, name=None)
  • regex:这是一个正则表达式,用于匹配URL路径。

  • views:这是处理该URL的视图函数。

  • kwargs:是一个可选的字典,用于传递额外的关键字参数给视图函数。这些参数将与URL捕获的参数一起传递给视图函数。

  • name=' ':这是URL模式的名称,用于反向解析URL。

    re_path(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive, name='year_archive')
    1. 在模板中

      <a href="{% url 'year_archive' year=2023 %}">2023 Articles</a>

    2. 在视图中

      from django.urls import reverse
      
      def some_view(request):
          url = reverse('year_archive', args=[2023])
          return redirect(url)

      使用reverse函数生成url,然后使用redirect函数重定向

3. models.py

4. urls.py

常用函数

  • render()

    from django.shortcuts import render
    
    def home_view(request):
        context = {
            'title': 'Home Page',
            'message': 'Welcome to our website!',
        }
        return render(request, 'home.html', context)
    1. request是当前的HTTP请求对象。

    2. 'home.html'是要渲染的模板文件的名称。

    3. context是一个字典,包含两个键值对:'title''message'。这些数据可以在模板中使用。

    home.html

    <!DOCTYPE html>
    <html>
    <head>
        <title>{{ title }}</title>
    </head>
    <body>
        <h1>{{ message }}</h1>
    </body>
    </html>

    在这个模板中,{{ title }}{{ message }}将分别被替换为'Home Page''Welcome to our website!'

  • redirect()

    使用 redirect 函数重定向

    from django.shortcuts import redirect
    
    def my_view(request):
        # 重定向到另一个视图
        return redirect('another_view')
    
    def another_view(request):
        # 处理另一个视图的逻辑
        return render(request, 'another_template.html')

    重定向到外部URL

    from django.shortcuts import redirect
    
    def my_view(request):
        # 重定向到外部URL
        return redirect('https://www.example.com')

    重定向时传递参数

    from django.shortcuts import redirect
    
    def my_view(request):
        # 重定向到另一个视图并传递参数
        return redirect('another_view', param1='value1', param2='value2')

  • 15
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值