草稿三

作者: 费云帆 | 来源:发表于2020-01-22 08:52 被阅读0次

    ● include标签:导入其他html代码,避免重复代码
    语法:{% include 'header.html' %}
    示例:

    <1>新建'template'目录,放置模板html,例如'header.html','footer.html'

    header.html

    <header>
    <ul>
    <li><a href="/">Index page</a></li> # href='/'表示指向根目录url
    <li><a href="{% url 'school' %}">School page</a></li>
    <li><a href="{% url 'company' %}">Company page</a></li>
    </ul>
    </header>

    footer.html

    <footer>



    <p>This is footer.</p>
    </footer>

    <2>新建首页名为'index.html',我们可以这样使用include标签:

    index.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>Title</title>
    </head>
    <body>
    {% include 'header.html' %} # 头部和尾部使用include导入,中间部分自己写
    <div class="content">This is index middle content.</div>
    {% include 'footer.html' %}
    </body>
    </html>

    company.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>Title</title>
    </head>
    <body>
    {% include 'header.html' %}
    <div class="content">This is Company Middle content.</div>
    {% include 'footer.html' %}
    </body>
    </html>

    school.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>Title</title>
    </head>
    <body>
    {% include 'header.html' %}
    <div class="content">This is School Middle content.</div>
    {% include 'footer.html' %}
    </body>
    </html>

    view

    from django.shortcuts import render
    from django.http import HttpResponse

    def index(request):
    return render(request,'index.html')

    def company(request):
    return render(request,'Company.html')

    def school(request):
    return render(request,'school.html')

    注意:若涉及到view中的context,规则是这样的:
    比如view传出来的context给html(这个html可以成为'子模板'),子模板可以使用这个变量
    同时,其关联的父模板,也可以使用这个变量;但是...其他子模板是不能直接使用父模板这个变量的
    (因为这个变量是由子模板给的),若想用,只能手动拼接
    示例:

    views

    def index(request):
    context={
    'username':'Jim Green'
    }
    return render(request,'index.html',context=context)

    index.html

    <body>
    {% include 'header.html' %}
    {{ username }}
    <div class="content">This is index middle content.</div>
    {% include 'footer.html' %}
    </body>

    header.html

    <header>
    <ul>
    <li><a href="/">Index page</a></li>
    <li><a href="{% url 'school' %}">School page</a></li>
    <li><a href="{% url 'company' %}">Company page</a></li>
    <li>{{ username }}</li>
    </ul>
    </header>

    上述页面,能够正常显示'username'的值,但是访问'school'链接或者'company'链接
    就不能显示'username',此时,在'school/company.html'中,我们这么处理,手动拼接:

    company.html

    <body>
    {% include 'header.html' with username='Jim Green' %}
    <div class="content">This is Company Middle content.</div>
    {% include 'footer.html' %}
    </body>

    这样就可以正常显示了.

    ● extends标签:模板继承
    示例:

    首先定义基模板---'base.html'

    base.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>Title</title>
    </head>
    <body>
    {% include 'header.html' %}
    <div class="content">
    {% block content %} # 中间部分,就是子模板需要自定义的内容
    <p>This is 'Base Html File'.</p>
    {% endblock %}
    </div>
    {% include 'footer.html' %}
    </body>
    </html>

    首页,更改为这样:

    {% extends 'base.html' %}
    {% block content %}
    <h1>Index Page.</h1> # 插入我们自定义的内容
    {% endblock %}

    有个问题有没有发现,这里若想继承基模板的这句话(<p>This is 'Base Html File'.</p>),该怎么处理?
    答案是---{{ block.super }}

    index.html

    {% extends 'base.html' %}
    {% block content %}
    <h1>Index Page.</h1>
    {{ block.super }} # 加这句就可以继承父模板中间的部分的所有东东
    {% endblock %}

    注意:在index.html的{{% endblock %}}外面添加任何语句,都会被忽略,没有显示.只能包含在{{% endblock %}}里面

    ★ 静态文件---static

    <1>首先,保证以下文件有装上去

    settings

    INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles', # 注意这个
    'front',
    ]

    STATIC_URL = '/static/'

    <2>添加根目录路径,示例:

    settings

    STATIC_URL = '/static/'
    STATICFILES_DIRS=[
    os.path.join(BASE_DIR,'static') # 指定django默认的静态文件位置
    ]

    注意:这里如果不指明'STATICFILES_DIRS'变量,那么django会自动到各个app底下去寻找
    示例:

    新建app---'front'
    'front'---'static'目录---'front'目录---'index.css'文件

    <3>项目根目录新建'static'文件夹,随便放入图片,例如'example.png'
    现在访问:'http://127.0.0.1:8000/static/example.png',成功显示图片

    在模板中如何显示图片呢?

    处理方式一:硬编码

    views

    rom django.shortcuts import render

    def index(request):
    return render(request,'index.html')

    index.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>Title</title>
    </head>
    <body>
    <h1>This is front index page,here are picture site</h1>
    <img src="static/example.png" alt="Show Picture"> # 指明图片路径
    </body>
    </html>

    刷新网页,成功显示图片

    处理方式二:使用static标签
    示例:

    index.html

    {% load static %} # 加载static标签
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>Title</title>
    </head>
    <body>
    <h1>This is front index page,here are picture site</h1>
    <img src="{% static 'example.png' %}" alt="Show Picture"> # static+filename
    </body>
    </html>

    刷新网页,成功显示图片

    注意:这里如果不想使用这句'{% load static %}',我们可以在settings中这么设置:

    TEMPLATES = [
    {
    'BACKEND': 'django.template.backends.django.DjangoTemplates',
    'DIRS': [os.path.join(BASE_DIR,'templates')],
    'APP_DIRS': True,
    'OPTIONS': {
    'context_processors': [
    'django.template.context_processors.debug',
    'django.template.context_processors.request',
    'django.contrib.auth.context_processors.auth',
    'django.contrib.messages.context_processors.messages',
    ],
    'builtins':['django.templatetags.static'], # 加上这句,可以在模板中省略load static
    },
    },
    ]

    • css渲染示例:

    'static'目录里面,新建'css'目录,在这个目录里面新建'index.css'

    index.css

    body{
    background-color: aquamarine;
    }

    index.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="{% static 'css/index.css' %}"> # 渲染样式
    </head>
    <body>
    <h1>This is front index page,here are picture site</h1>
    <img src="{% static 'example.png' %}" alt="Show Picture">
    </body>
    </html>

    ● 'django.contrib.staticfiles'在settings中若删除这句,需手动配置静态文件
    有兴趣可以看看


    数据库

    ● django默认使用'sqlite'
    示例:

    settings

    DATABASES = {
    'default': {
    'ENGINE': 'django.db.backends.sqlite3',
    'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
    }

    现在把它配置成'mysql'
    示例:

    DATABASES = {
    'default': {
    'ENGINE': 'django.db.backends.mysql',
    'NAME': 'django_db1',
    'USER':'root',
    'PASSWORD':'root',
    # DB地址(虽然和django一样,但是端口不同,所以地址其实也是不一样的)
    'HOST':'127.0.0.1',
    # 这行可写,可不写,默认端口
    'PORT':'3306' # 这里'3306'是字符串
    }
    }

    ● 使用django操作db的方法有两个,一是原生sql语句,二就是ORM

    原生sql示例:

    • 比如说设置id为主键(那么它就会自动增长)
    首先使用navicat连接了mysql数据库,新建一个django_db1的数据库。然后django_db1中新建一个book的表,有三个值id(主键,自动增长),name,author。

    views

    from django.shortcuts import render
    from django.db import connection

    def index(request):
    cursor=connection.cursor() # 建立游标
    # 执行SQL语句
    # 这里id值虽然赋值null,但是mysql会自动标记为'1'
    cursor.execute("insert into book(id,name,author) values (null,'Learning English','Jim Green')")
    return render(request,'index.html')

    启动服务,刷新网页虽然什么都没有,但是数据库中已经插入了我们写的一条记录
    现在,执行另一条SQL语句

    示例:

    from django.shortcuts import render
    from django.db import connection

    def index(request):
    cursor=connection.cursor()
    #cursor.execute("insert into book(id,name,author) values (null,'Learning English','Jim Green')")
    cursor.execute("select id,name,author from book")
    rows=cursor.fetchall() # 使用fetchall()获取所有的结果,存储在变量rows
    for row in rows:
    print(row) # 打印所有的结果
    return render(request,'index.html')


    图书管理系统

    <1>settings就不写啦(默认templates记得写)

    front/views

    from django.shortcuts import render
    from django.db import connection

    cursor对象需要经常调用,所以封装成函数

    def get_cursor():
    return connection.cursor()

    def index(request):
    cursor=get_cursor()
    cursor.execute("select * from book")
    books=cursor.fetchall()
    return render(request,'index.html',context=dict(books=books))

    def add_book(request):
    pass

    def book_detail(request,book_id):
    pass

    urls.py

    from django.contrib import admin
    from django.urls import path
    from front import views

    urlpatterns = [
    path('admin/', admin.site.urls),
    path('', views.index,name='index'),
    path('add_book/', views.add_book,name='add_book'),
    path('book_detail/', views.book_detail,name='book_detail'),
    ]

    <2>静态文件存放于'front-static-front'
    模板文件存放于'templates'

    index.html

    {% extends 'base.html' %} # 继承base模板
    {% block content %}
    <table>
    <thead>
    <tr>
    <th>序号</th>
    <th>书名</th> # 表头
    <th>作者</th>
    </tr>
    </thead>
    <tbody>
    {% for book in books %}
    <tr> # 内容
    <td>{{ forloop.counter }}</td> # 序号
    <td>{{ book.1 }}</td> # 访问元组的第一个元素---书名
    <td>{{ book.2 }}</td> # 访问元素的第二个元素---作者
    </tr>
    {% endfor %}
    </tbody>
    </table>
    {% endblock %}

    base.html

    {% load static %}
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>图书管理系统</title>
    <link rel="stylesheet" href="{% static 'front/base.css' %}"> # 注意样式
    </head>
    <body>
    <nav> # nav表示导航条
    <ul class="nav">
    <li><a href="/">首页</a></li>
    <li><a href="{% url 'add_book' %}">发布图书</a></li>
    </ul>
    </nav>
    {% block content %}

    {% endblock %}
    

    </body>
    </html>

    base.css

    *{ # 使导航条完全靠左边(删除多余的空隙)
    margin: 0;
    padding: 0;
    }

    .nav{ # 导航条操作
    background-color: #3a3a3a;
    height: 65px; # 导航条高度
    overflow: hidden; # 若有多余的元素,则隐藏
    }

    .nav li{
    float: left; # 文字向左浮动
    list-style: none; # 删除列表符号
    margin: 0 20px; # 文字之间的间距(默认是挤在一起)
    line-height: 65px;# 文字位于导航条中间
    }

    .nav li a{
    color: #fff;
    text-decoration: none; # 删除链接下划线效果
    }

    .nav li a:hover{ # 鼠标移到链接效果
    color: lightblue;
    }

    • 下面,为图书管理系统添加一个'增加图书'的功能

    views

    def add_book(request):
    if request.method=='GET':
    return render(request,'add_book.html')
    else:
    # 获取前端提交的数据
    name=request.POST.get('name')
    author=request.POST.get('author')
    cursor=get_cursor()
    # 注意values的值,必须为字符串;若省略单引号,就报错
    cursor.execute("insert into book(id,name,author) values(null,'{0}','{1}') ".format(name,author))
    # 提交完成,重定向到首页
    return redirect(reverse('index'))

    add_book.html

    {% extends 'base.html' %}
    {% block content %}
    <form action="" method="post"> # 插入数据库的操作,必须以表单post的形式提交
    <table> # action留空,仍然用当前的url来调用后端视图
    <tbody> # 后端视图最终重定向到首页
    <tr>
    <td>书名</td>
    <td><input type="text" name="name"></td>
    </tr>
    <tr>
    <td>作者</td>
    <td><input type="text" name="author"></td>
    </tr>
    <tr>
    <td></td>
    <td><input type="submit" value="提交"></td>
    </tr>
    </tbody>
    </table>
    </form>
    {% endblock %}

    • 添加书籍细节和'删除'功能

    views

    def book_detail(request,book_id):
    cursor=get_cursor()
    cursor.execute("select * from book where id={}".format(book_id))
    # 获取单条结果
    book=cursor.fetchone()
    return render(request,'book_detail.html',context=dict(book=book))

    book_detail.html

    {% extends 'base.html' %}
    {% block content %}
    # 获取书名和作者
    <p>{{ book.1 }}</p>
    <p>{{ book.2 }}</p>
    # 添加删除图书的按钮(需动到数据库,所以使用表单post)
    <form action="{% url 'delete_book' %}" method="post"> # 这里需要指向'delete_book' url,这个url来调用后端删除视图
    <input type="hidden" name="book_id" value="{{ book.0 }}"> # 需要删除的字段,隐藏
    <input type="submit" value="删除图书">
    </form>
    {% endblock %}

    urls

    path('delete_book/', views.delete_book,name='delete_book'),

    views

    def delete_book(request):
    if request.method=='POST':
    book_id=request.POST.get('book_id') # 获取前端传过来的数据
    curse=get_cursor()
    curse.execute("delete from book where id={}".format(book_id))
    return redirect(reverse('index'))
    else:
    raise RuntimeError('类型错误')


    ORM 模型

    ● 增,删,改,查

    <1>增---var.save() # create() or get_or_create()
    <2>查---var.objects.get(pk=1)
    或者 var.objects.filter(author='Jim Green')
    <3>删---先'查',然后 var.delete()
    <4>改---先'查',然后 var.price=500 var.save()

    '''review''':调用objects.xxx()以后,不管返回的是'QuerySet对象'还是"模型对象",都可以进行遍历,并通过'.'号形式访问字段
    例如:'book.name','book.price'

    完整示例:
    新建book app

    models

    from django.db import models

    必须继承models的子类

    class Book(models.Model):

    # id这句有无均可
    id=models.AutoField(primary_key=True)
    
    name=models.CharField(max_length=100,null=False)
    author=models.CharField(max_length=100,null=False)
    price=models.FloatField(null=False,default=0)
    # python manage.py makemigrations 生成迁移脚本
    # python manage.py migrate 写入数据库
    
    def __str__(self):
        query_message='<book:{0},{1},{2},{3}>'.format(self.id,self.name,self.author,self.price)
        return query_message
    

    class Publisher(models.Model):
    # 虽然没有id字段,但是django会在数据库自动生成这句
    name=models.CharField(max_length=100,null=False)
    address=models.CharField(max_length=100,null=False)

    views

    from django.shortcuts import render
    from django.http import HttpResponse
    from .models import Book

    def index(request):
    # 增
    # book=Book(id=1,name='Learn Knowledge',author='Jim Green',price=200)
    # book.save()

    # 查
    # 查询要通过objects对象来获取
    # pk对应主键(无视你的主键叫什么名字)
    #book=Book.objects.get(pk=1)
    #print(book)
    #book=Book.objects.filter(author='Jim Green')
    '''book=Book.objects.filter(author='Jim Green').first()
       book=Book.objects.filter(author='Jim Green')[0]'''
    #print(book)
    
    # 删
    # book=Book.objects.get(pk=2)
    # book.delete()
    
    #改
    book=Book.objects.get(pk=1)
    book.price=500
    book.save()
    return HttpResponse('Book added successfully')
    

    urls

    from django.contrib import admin
    from django.urls import path
    from book import views

    urlpatterns = [
    path('admin/', admin.site.urls),
    path('', views.index),
    ]

    ● 常用的字段介绍
    示例:

    class Article(models.Model):

    id=models.BigAutoField(primary_key=True) # BigAutoField的范围 > AutoField
    removed=models.NullBooleanField() # BooleanField表示布尔型,但是null不能为空,而这个字段可以为空
    title=models.CharField(max_length=100) # 布尔型只有两种值,所以不可能为null
    text=models.TextField(max_length=1000,null=True) # TextField字段 > CharField
    

    • 时间型字段介绍
    示例:

    import pytz # 处理时区
    from datetime import datetime # 时间对象

    now=datetime.now()
    now
    datetime.datetime(2019, 11, 21, 9, 43, 4, 182157)

    utc_timezone=pytz.timezone('UTC') # 获取格林尼治标准时区
    utc_timezone
    <UTC>

    now.astimezone(utc_timezone) # 当前时间转换成'格林尼治时区'时间
    Traceback (most recent call last):
    File "<pyshell#6>", line 1, in <module>
    now.astimezone(utc_timezone)
    ValueError: astimezone() cannot be applied to a naive datetime

    注意:区分这两个概念

    <1>naive datetime --- '幼稚'的时间,没有确切身份的时间.本例中,now对象只表示当前时间,没有时区
    <2>aware datetime --- '成熟'的时间,有具体的时间及时区认证.

    replace()方法---非原地修改,替换当前时间的值(比如月份,天数,小时等等)

    now.replace(day=22)
    datetime.datetime(2019, 11, 22, 9, 43, 4, 182157)
    now
    datetime.datetime(2019, 11, 21, 9, 43, 4, 182157)

    现在问题的症结就在于,now对象是没有'时区身份'的,那么,我们利用replace方法,把时区加进去:

    now=now.replace(tzinfo=pytz.timezone("Asia/Shanghai")) # 使用tzinfo关键字参数,指明要用的时区
    now # 此时的now,就是aware 对象了
    datetime.datetime(2019, 11, 21, 9, 43, 4, 182157, tzinfo=<DstTzInfo 'Asia/Shanghai' LMT+8:06:00 STD>)
    utc_now=now.astimezone(utc_timezone) # 再次进行转换,就不会报错啦
    utc_now
    datetime.datetime(2019, 11, 21, 1, 37, 4, 182157, tzinfo=<UTC>)

    小结:

    <1>pytz库---使用的只有一个方法:pytz.timezone()
    传入的值有两个:pytz.timezone('UTC'),pytz.timezone('Asia/Shanghai')

    <2>now对象方法---now.astimezone()---传入其他时区对象
    ---now.replace()---now.replace(day=2)
    ---now.replace(tzinfo=pytz.timezone('UTC'))

    复习版1:

    import pytz
    from datetime import datetime
    utc_timezone=pytz.timezone('UTC')
    now=datetime.now()
    now=now.replace(tzinfo=pytz.timezone('Asia/Shanghai'))
    now
    datetime.datetime(2019, 11, 21, 10, 19, 38, 369600, tzinfo=<DstTzInfo 'Asia/Shanghai' LMT+8:06:00 STD>)
    now.astimezone(utc_timezone)
    datetime.datetime(2019, 11, 21, 2, 13, 38, 369600, tzinfo=<UTC>) # 时间提前了 8 小时

    settings

    TIME_ZONE = 'UTC'
    USE_TZ = True # 这里若为False,那么就是naive类型的时间

    views

    from django.utils.timezone import now # 查看now源码(make_aware也是在timezone)

    def now(): # 根据USE_TZ的取值,要么返回aware对象,要么返回naive对象
    """
    Return an aware or naive datetime.datetime, depending on settings.USE_TZ.
    """
    if settings.USE_TZ:
    # timeit shows that datetime.now(tz=utc) is 24% slower
    return datetime.utcnow().replace(tzinfo=utc)
    else:
    return datetime.now()

    • review:把一个naive time转换成aware time,还可以利用django的make_aware()方法
    操作起来非常简便,示例:

    from datetime import datetime
    from django.utils.timezone import make_aware

    time=datetime.now()
    print(time) # 2019-12-05 14:38:01.765347
    aware_time=make_aware(time)
    print(aware_time) # 2019-12-05 14:38:01.765347+08:00

    ● DateTimeField 字段

    settings

    TIME_ZONE = 'Asia/Shanghai'

    USE_TZ = True

    index

    {% load tz %} # 加载时区
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>Title</title>
    </head>
    <body>
    <p>{{ create_time|localtime }}</p> # 效果一样:{{ create_time }}
    </body>
    </html>

    models

    class Article(models.Model):

    id=models.BigAutoField(primary_key=True)
    removed=models.NullBooleanField()
    title=models.CharField(max_length=100)
    text=models.TextField(max_length=1000,null=True)
    #create_time=models.DateTimeField()
    #create_time=models.DateTimeField(auto_now_add=True) # 参数以现在的时间作为创建时间
    create_time=models.DateTimeField(auto_now=True)# 每次调用save()方法,就更新当前时间
    

    views

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

    若使用django,就用django的now,少用datetime的now

    from django.utils.timezone import now,localtime

    def index(request):

    # 获取的是UTC的时间
    #article=Article(title='Learn to live',text='Now  the content is ...',create_time=now())
    #article.save()
    
    #article=Article.objects.get(pk=4)
    # create_time=article.create_time # 获取数据库时间(这里是"UTC)时间
    # now=localtime(create_time) # 转换成现在的时间
    # print('*'*30)
    # print(create_time)
    # print(now)
    # print('*'*30)
    #article=Article(title='Do Nothing',text='That is all...')
    #article.save()
    article=Article.objects.get(pk=7)
    article.title='Windows change'
    article.save()
    return HttpResponse('successfully')
    #return render(request,'index.html',context=dict(create_time=create_time))
    

    ● Field常用参数解析

    <1>null---表示什么都没有,即'无'
    区分空字符串---''

    在DB里面的区分尤其明显---数据库中,若值允许为null,会有明显的'null'标识
    若为空字符串,则什么都没有显示

    在'models.CharField' 中,最好默认null=False,因为如果实例化不插入值,django会插入空字符串
    此时,若null=True,很容易产生歧义(虽然打开数据库可以去辨别...)

    <2> db_column---更改字段在数据库中的名字

    age=models.IntegerField(null=True,db_column='person_age')

    <3> default---默认值:可以是数值,有可以是函数对象(若写成'func()'那就是定值了...而只有写成函数对象,获取的结果才是动态的)

    from django.utils.timezone import now

    class Person(models.Model):
    username=models.CharField(max_length=50)
    age=models.IntegerField(null=True,db_column='person_age',default=18)
    create_time=models.DateTimeField(default=now) # default的值就是函数对象

    <4> unique属性---唯一键(也就是定义该字段的值,只能唯一,不能重复),值为布尔型

    models

    ...
    telephone = models.CharField(max_length=11, unique=True, null=True)

    views

    def person(request):
    p=Person(telephone='123456789') # 只能执行一次,执行第二次会报错,因为键唯一
    p.save()
    return HttpResponse('Successful')

    • Meta类的字段---针对模型的操作
    示例:

    class Meta:
        db_table='person_model' # 重命名数据库
        ordering=['-create_time'] # 对数据库字段进行排序,注意格式是list,可以添加多字段排序
    

    ● 外键---实质就是'关联'

    mysql中有好几种引擎,我们常用的就是 'InnoDB' ,这个引擎是支持外键约束的
    使用外键,我们可以引用别的数据表的字段来丰富内容
    我们说的外键,实际上是'外键id',关联的是另一张表的主键id. # 请记住这句话
    此时的外键,关联的是另一张表其中的一整行数据
    示例:

    article.models

    from django.db import models

    class Category(models.Model):
    name=models.CharField(max_length=100)

    class Article(models.Model):
    title=models.CharField(max_length=150)
    content=models.TextField()
    # article表里面并没有category字段,而是'category_id'字段
    # 但是,通过ORM,我们操作category字段,实际操作关联的就是'category_id'字段
    category=models.ForeignKey('Category',on_delete=models.CASCADE)

    注意:生成数据表后,article表会多出一个字段'category_id',这个字段就是外键,用来关联'category'数据表

    foreign_db.urls

    from django.contrib import admin
    from django.urls import path,include
    urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('article.urls')),
    ]

    article.urls

    from django.urls import path
    from . import views

    app_name='article'

    urlpatterns = [
    path('',views.index,name='index'),
    ]

    article.views

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

    def index(request):
    # 实例化的时候,无需实例化外键
    article=Article(title='How to study...',content='Thi is a ...')
    category=Category(name='Jim Green')
    category.save() # 实例化后,必须保存,否则会报错
    article.category=category
    article.save()
    return HttpResponse('Successful!')

    • 如何访问外键的字段---通过'.'符号,示例:

    def index(request):

    article=Article.objects.first() # first()获取第一条数据,返回的是模型对象
    print(article.category) # 获取的是category模型对象
    print(article.category.name) # 访问具体的字段名:Jim Green
    return HttpResponse('Successful!')
    

    • 如果想用别的app的字段作为外键,该怎么处理?示例:

    front.models

    from django.db import models

    class FrontUser(models.Model):
    front_user=models.CharField(max_length=50)

    article.models

    from django.db import models

    class Category(models.Model):
    name=models.CharField(max_length=100)

    class Article(models.Model):
    title=models.CharField(max_length=150)
    content=models.TextField()
    category=models.ForeignKey('Category',on_delete=models.CASCADE)
    # 通过'app.ModelName'的形式访问
    # 由于是插入的字段,得允许为null,不然前面的字段怎么办...
    author=models.ForeignKey('front.FrontUser',on_delete=models.CASCADE,null=True)

    • 以表自身的字段(以自身模型)作为外键(这种实际需求是存在的,只是还没碰到),示例:

    class Comment(models.Model):
    content=models.CharField(max_length=200)
    # 使用'self'表示自身
    orgin_comment=models.ForeignKey('self',on_delete=models.CASCADE)

    小结:使用外键的时候,针对两个数据表而言,'谁'影响'谁'要搞清楚

    相关文章

      网友评论

          本文标题:草稿三

          本文链接:https://www.haomeiwen.com/subject/haeuzctx.html