您现在的位置是:主页 > news > c 网站开发 环境配置/锦绣大地seo
c 网站开发 环境配置/锦绣大地seo
admin2025/6/17 18:32:29【news】
简介c 网站开发 环境配置,锦绣大地seo,wordpress账户密码为空,wordpress 登录限制文章目录1. 书籍展示和书籍添加_编辑_删除1.1 代码编写流程1.2 项目主目录代码django_orm1.3 图书系统应用booksys1.4 静态文件static1.5 前端渲染模板template2. 13个查询api接口3. 表关系设计4. 级联解释5. 多表关系记录的添加6. 小提示和小练习1. 书籍展示和书籍添加_编辑_删…
c 网站开发 环境配置,锦绣大地seo,wordpress账户密码为空,wordpress 登录限制文章目录1. 书籍展示和书籍添加_编辑_删除1.1 代码编写流程1.2 项目主目录代码django_orm1.3 图书系统应用booksys1.4 静态文件static1.5 前端渲染模板template2. 13个查询api接口3. 表关系设计4. 级联解释5. 多表关系记录的添加6. 小提示和小练习1. 书籍展示和书籍添加_编辑_删…
文章目录
- 1. 书籍展示和书籍添加_编辑_删除
- 1.1 代码编写流程
- 1.2 项目主目录代码django_orm
- 1.3 图书系统应用booksys
- 1.4 静态文件static
- 1.5 前端渲染模板template
- 2. 13个查询api接口
- 3. 表关系设计
- 4. 级联解释
- 5. 多表关系记录的添加
- 6. 小提示和小练习
1. 书籍展示和书籍添加_编辑_删除
1.1 代码编写流程
1. 在项目中创建app(这里面的数据库引用的其他app,所以要执行一遍数据库迁移指令)python manage.py startapp booksys2. 创建好的应用要和项目关联起来在setting.py中INSTALL_APPS中添加booksys3. 在url.py中配置url路径from booksys import views as book_viewurl(r'^books/',book_view.books)4. 在booksys下的views中写视图函数def books(request):return render(request,'books.html')5. 在template下创建books.html6. 要用到bootstrap,就要涉及到静态文件的引入,在settings.py中进行设置STATICFILES_DIRS = [os.path.join(BASE_DIR,'statics')
]7. 在根下创建一个statics文件夹,在文件夹下创建book文件夹,里面存放自定义文件如css、js、img,在创建一个plugins文件夹用来放bootstrap、jquery,然后在books.html中引用加载静态文件8. 开始在books.html表中写样式,表格里面的内容要用循环<tr><td></td><tr>9. 展示数据,在views中导入models,从数据库中读取数据,然后通过模板渲染进行返回给用户,然后在books.html中写jinjia模板,进行模板渲染10 展示书籍已完成,然后就是添加书籍,添加url 到对应的view视图,然后写数据库语句,在template下创建一个add_book.html11. 因为书籍展示和书籍添加有的是一样的,所以写一个模板base.html
1.2 项目主目录代码django_orm
init.py
import pymysql
pymysql.install_as_MySQLdb()
settings.py
INSTALLED_APPS = ['django.contrib.admin','django.contrib.auth','django.contrib.contenttypes','django.contrib.sessions','django.contrib.messages','django.contrib.staticfiles','app01.apps.App01Config','booksys',
]MIDDLEWARE = ['django.middleware.security.SecurityMiddleware','django.contrib.sessions.middleware.SessionMiddleware','django.middleware.common.CommonMiddleware',# 'django.middleware.csrf.CsrfViewMiddleware','django.contrib.auth.middleware.AuthenticationMiddleware','django.contrib.messages.middleware.MessageMiddleware','django.middleware.clickjacking.XFrameOptionsMiddleware',
]TEMPLATES = [{'BACKEND': 'django.template.backends.django.DjangoTemplates','DIRS': [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',],},},
]DATABASES = {'default': {'ENGINE': 'django.db.backends.mysql','NAME': 'orm01','HOST': '127.0.0.1','PORT': 3306,'USER':'root','PASSWORD':'',}
}STATIC_URL = '/static/'STATICFILES_DIRS = [os.path.join(BASE_DIR,"statics")
]
urls.py
from django.conf.urls import url
from django.contrib import admin
from app01 import views
from booksys import views as book_viewurlpatterns = [url(r'^admin/', admin.site.urls),url(r'^query/', views.query),url(r'^books/',book_view.books),url(r'^add_book',book_view.add_book),url(r'^edit_book/(\d+)',book_view.edit_book), # 提交修改请求,http://127.0.0.1:8000/edit_book/2url(r'^del_book/(\d+)',book_view.del_book)
]
1.3 图书系统应用booksys
apps.py
from django.apps import AppConfigclass BooksysConfig(AppConfig):name = 'booksys'
models.py
from django.db import models# Create your models here.from django.db import models# Create your models here.class Book(models.Model):# 如果没有指定主键字段,默认orm会给这个表添加一个名称为id的主键自增字段# 如果指定了,以指定的为准,那么orm不在创建那个id字段了# nid = models.AutoField(primary_key=True) # int primary_key auto_incrementtitle = models.CharField(max_length=32) # varchar 书籍名称# price = models.FloatField()#price = models.DecimalField(max_digits=5,decimal_places=2) # 999.99pub_date = models.DateField() # data 出版日期publish = models.CharField(max_length=32) # 出版社名称# xx = models.CharField(max_length=18,null=True,blank=True) # null=True,blank=True允许该字段数据为空xx = models.CharField(max_length=18,default="xxx") #null=True,blank=True允许该字段数据为空
view.py
from django.shortcuts import render,HttpResponse,redirect
# 不同的应用创建不同的表
from booksys import models# Create your views here.
def books(request):book_list = models.Book.objects.all()return render(request,'books.html',{'book_list':book_list})def add_book(request):if request.method == 'GET':return render(request,'add_book.html')else:# request.POST是一个querydict类型,提供一个dict方法,把querydict转换成普通类型字典类型数据data = request.POST.dict()print(data)# print(request.POST)# title = request.POST.get('title')# price = request.POST.get('price')# pub_date = request.POST.get('pub_date')# publish = request.POST.get('publish')# print(title,title,pub_date,publish)# 关键字传参可以通过**打散的形式来传入ret = models.Book.objects.create(**data# title = title,# price = price,# pub_date = pub_date,# publish = publish,)return redirect('/books/')# return HttpResponse('ok')def edit_book(request,book_id):if request.method == 'GET':old_obj = models.Book.objects.get(id=book_id)return render(request,'edit_book.html',{'old_obj':old_obj})else:date = request.POST.dict()models.Book.objects.filter(id=book_id).update(**date)return redirect('/books/')def del_book(request,book_id):models.Book.objects.get(id=book_id).delete()return redirect('/books/')
1.4 静态文件static
book目录下放的是css、img、js各种样式
plugins是引用的bootstrap文件
1.5 前端渲染模板template
add_book.html
{% extends 'base.html' %}{% block content_title %}<h1>添加书籍</h1>
{% endblock %}{% block content %}{# 如果action中没有写路径,就往获取当前页面下进行提交 #}<form action="" method="post">{# 写csrf_token可以通过后台的认证 #}
{# {% csrf_token %}#}<div class="form-group"><label for="title">价格</label><input type="text" class="form-control" id="title" placeholder="书籍名称" name="title"></div><div class="form-group"><label for="price">价格</label><input type="number" class="form-control" id="price" placeholder="价格" name="price"></div><div class="form-group"><label for="pub_date">出版日期</label><input type="date" class="form-control" id="pub_date" placeholder="出版日期" name="pub_date"></div><div class="form-group"><label for="publish">出版社</label><input type="text" class="form-control" id="publish" placeholder="出版社" name="publish"></div>{# button默认type属性就是submit,可以触发form表单。如果只想要给普通的按钮,那么type属性就写成button,不能提交form表单数据#}{#<button type="button" class="btn btn-default">Submit</button>#}<button type="submit" class="btn btn-success">Submit</button></form>
{% endblock %}
base.html
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><link rel="stylesheet" href="{% static 'plugins/bootstrap-3.3.7-dist/css/bootstrap.min.css' %}"><meta name="viewport" content="width=device-width,initial-scale=1">
</head>
<body><div class="container">{% block content_title %}<h1 > 模板书籍 </h1>{% endblock %}<div class="row"><div class="col-md-8 col-md-offset-2">{% block content %}模板内容{% endblock %}</div></div>
</div></body>
<script src="{% static 'plugins/jquery.js' %}"></script>
<script src="{% static 'plugins/bootstrap-3.3.7-dist/js/bootstrap.min.js' %}"></script>
</html>
books.html
{% extends 'base.html' %}{% block content_title %}<h1>查看书籍</h1>
{% endblock %}{% block content %}<a href="/add_book" class="btn btn-primary">添加书籍</a><table class="table table-striped table-hover"><thead><tr><th>编号</th><th>书籍名称</th><th>价格</th><th>出版日期</th><th>出版社</th><th>操作</th></tr></thead><tbody>{% for book in book_list %}<tr><td>{{ forloop.counter }}</td><td>{{ book.title }}</td><td>{{ book.price }}</td><td>{{ book.pub_date | date:'Y-m-d' }}</td><td>{{ book.publish }}</td><td><a href="/edit_book/{{ book.id }}" class="btn btn-warning">编辑</a><a href="/del_book/{{ book.id }}" class="btn btn-danger">删除</a></td></tr>{% endfor %}</tbody></table>
{% endblock %}
edit_book.html
{% extends 'base.html' %}{% block content_title %}<h1>编辑书籍</h1>
{% endblock %}{% block content %}{# 如果action中没有写路径,就往获取当前页面下进行提交 #}<form action="" method="post">{# 写csrf_token可以通过后台的认证 #}
{# {% csrf_token %}#}<div class="form-group"><label for="title">价格</label><input type="text" value="{{ old_obj.title }}" class="form-control" id="title" placeholder="书籍名称" name="title"></div><div class="form-group"><label for="price">价格</label><input type="number" value="{{ old_obj.price }}" class="form-control" id="price" placeholder="价格" name="price"></div><div class="form-group"><label for="pub_date">出版日期</label><input type="date" value="{{ old_obj.pub_date | date:"Y-m-d" }}" class="form-control" id="pub_date" placeholder="出版日期" name="pub_date"></div><div class="form-group"><label for="publish">出版社</label><input type="text" value="{{ old_obj.publish }}" class="form-control" id="publish" placeholder="出版社" name="publish"></div>{# button默认type属性就是submit,可以触发form表单。如果只想要给普通的按钮,那么type属性就写成button,不能提交form表单数据#}{#<button type="button" class="btn btn-default">Submit</button>#}<button type="submit" class="btn btn-success">Submit</button></form>
{% endblock %}
2. 13个查询api接口
还记得表类.objects像是一个管理器,提供了增删改查的方法,Book.objects.all()获取所有的书籍,查询这里大家就掌握谁调用的下面的方法
<1> all(): 查询所有结果,结果是queryset类型<2> filter(**kwargs): 它包含了与所给筛选条件相匹配的对象,结果也是queryset类型 Book.objects.filter(title='linux',price=100) #里面的多个条件用逗号分开,并且这几个条件必须都成立,是and的关系,or关系的我们后面再学,直接在这里写是搞不定or的<3> get(**kwargs): 返回与所给筛选条件相匹配的对象,不是queryset类型,是行记录对象,返回结果有且只有一个,如果符合筛选条件的对象超过一个或者没有都会抛出错误。捕获异常try。 Book.objects.get(id=1)<4> exclude(**kwargs): 排除的意思,它包含了与所给筛选条件不匹配的对象,没有不等于的操作昂,用这个exclude,返回值是queryset类型 Book.objects.exclude(id=6),返回id不等于6的所有的对象,或者在queryset基础上调用,Book.objects.all().exclude(id=6)<5> order_by(*field): queryset类型的数据来调用,对查询结果排序,默认是按照id来升序排列的,返回值还是queryset类型models.Book.objects.all().order_by('price','id') #直接写price,默认是按照price升序排列,按照字段降序排列,就写个负号就行了order_by('-price'),order_by('price','id')是多条件排序,按照price进行升序,price相同的数据,按照id进行升序<6> reverse(): queryset类型的数据来调用,对查询结果反向排序,返回值还是queryset类型<7> count(): queryset类型的数据来调用,返回数据库中匹配查询(QuerySet)的对象数量。<8> first(): queryset类型的数据来调用,返回第一条记录 Book.objects.all()[0] = Book.objects.all().first(),得到的都是model对象,不是queryset<9> last(): queryset类型的数据来调用,返回最后一条记录<10> exists(): queryset类型的数据来调用,如果QuerySet包含数据,就返回True,否则返回False空的queryset类型数据也有布尔值True和False,但是一般不用它来判断数据库里面是不是有数据,如果有大量的数据,你用它来判断,那么就需要查询出所有的数据,效率太差了,用count或者exits例:all_books = models.Book.objects.all().exists() #翻译成的sql是SELECT (1) AS `a` FROM `app01_book` LIMIT 1,就是通过limit 1,取一条来看看是不是有数据<11> values(*field): 用的比较多,queryset类型的数据来调用,返回一个ValueQuerySet——一个特殊的QuerySet,运行后得到的并不是一系列model的实例化对象,而是一个可迭代的字典序列,只要是返回的queryset类型,就可以继续链式调用queryset类型的其他的查找方法,其他方法也是一样的。
<12> values_list(*field): 它与values()非常相似,它返回的是一个元组序列,values返回的是一个字典序列<13> distinct(): values和values_list得到的queryset类型的数据来调用,从返回结果中剔除重复纪录
举例子:
# 127.0.0.1:8000/query
from django.shortcuts import render,HttpResponse
from app01 import models
import datetime
# Create your views here.
def query(request):# exclude排除# 返回结果为queryset类型数据,通过objects控制器可以调用,queryset类型数据也能调用# obj_list = models.Book.objects.exclude(id=2)# obj_list = obj_list.filter(title='少年1')# obj_list = obj_list.all()# obj_list = models.Book.objects.exclude(id=2).filter(title__contains='少年').exclude(id=5)# order_by 排序# 返回结果为queryset类型数据,queryset类型数据可以调用这个方法# obj_list = models.Book.objects.all().order_by('-id') #-id加个-号表示按照该字段降序排列, desc asc# '''select * from app01_book order by id desc;'''# obj_list = models.Book.objects.all().order_by('price', '-id') #按照价格升序排列,价格相同的按照id降序排列# reverse()# 翻转必须在排序数据的基础上# 返回结果为queryset类型数据,queryset类型数据可以调用这个方法# obj_list = models.Book.objects.all().order_by('-id').reverse()# count# queryset类型数据可以调用这个方法,返回值为数字# obj_list = models.Book.objects.all().count()# first\last# queryset类型数据可以调用这个方法,返回值为模型类对象# obj_list = models.Book.objects.all().first()# obj_list = models.Book.objects.all()[0]# obj_list = models.Book.objects.all().last()# exists# 判断查询结果是有数据# queryset类型数据可以调用这个方法# obj_list = models.Book.objects.all().exists() #判断是否有数据的效率高,只找一条记录 limit 1# values# 可以获取指定字段数据# objects可以调用, queryset也能调用,返回结果还是queryset,内容为一个个字典数据# obj_list = models.Book.objects.values('title', 'price')# obj_list = models.Book.objects.filter(id=5).values('title', 'price')# values_list# 可以获取指定字段数据,返回结果还是queryset,内容为一个个元组数据# obj_list = models.Book.objects.values_list('title', 'price')# obj_list = models.Book.objects.filter(id=5).values_list('title', 'price')# distinct 去重# 一般配合values和values_list来使用# distinct 去重的是整条记录,整条记录重复才是重复,要指定去重的字段才有意义obj_list = models.Book.objects.values('price').distinct()print(obj_list)return HttpResponse('ok')
小提示: 有queryset方法大全,可以进行查看
3. 表关系设计
from django.db import models# Create your models here.# 作者表
class Author(models.Model):name = models.CharField( max_length=32)age = models.IntegerField()# django2.x版本必须手动指定on_delete=models.CASCADE级联模式# au = models.OneToOneField(to="AuthorDetail", to_field="id", on_delete=models.CASCADE)# au = models.OneToOneField("AuthorDetail")# au = models.IntegerField()au = models.OneToOneField("AuthorDetail", db_constraint=False)# db_constraint=False取消foreign key的强制约束效果,还可以继续使用orm的提供的属性或者方法来操作关系记录# foreign key + unique# 属性是OneToOneField或者ForeignKey,那么生成的对应字段是 属性名称_id#作者详细信息表
class AuthorDetail(models.Model):birthday=models.DateField()telephone=models.BigIntegerField()addr=models.CharField(max_length=64)# 出版社表
class Publish(models.Model):name=models.CharField( max_length=32)city=models.CharField( max_length=32)#书籍表
class Book(models.Model):title = models.CharField( max_length=32)publishDate=models.DateField()price=models.DecimalField(max_digits=5,decimal_places=2)# publishs=models.ForeignKey(to="Publish",to_field="id",on_delete=models.CASCADE)publishs=models.ForeignKey("Publish")authors = models.ManyToManyField('Author')# class authortobook(models.Model):
# book_id = models.ForeignKey('Book')
# author_id = models.ForeignKey('Author')
4. 级联解释
举例子来说明表设计(下面的表操作都是按照下面的例子来看):
作者和作者详细信息是一对一关系(在哪个表写关联关系都可以,这里写到了作者里面)
解释:如果写在作者表这块,如果删除作者详情里的表记录并且关联了作者表,则都会删除。如果删除作者表,则不会删除作者信息表。通俗理解,作者表抱着作者详情表的大腿,详情表的记录没了,关联作者表的内容也没了。作者表记录没了,不会影响作者详细表内容。提示:OneToOneField生成的字段是属性名称_id书籍表和出版社表是多对一关系(在多的那张表写关联关系,这里写到了书籍表中)
提示:ForeignKey属性生成的字段是属性名称_id,删除书不影响出版社,因为书籍表中有外键书籍表和作者表是多对多关系(在哪个表写关联关系在都可以,这里写到了书籍表中)
解释:authors = models.ManyToManyField('Author')不会在当前表(Book)创建author字段,而是会自动创建一张新表app01_book_authors(名字组成应用名称+模型类小写+关联关系属性), 删除作者表和书籍表中的内容只会对第三表产生影响,因为自动生成的表中的foreignkey都指向book、author表,book和author不会相互影响。app01_book_authors中有id、book_id、author_id, 而且authors这个字段还可以操控自动生成的第三张表foreignKey强制约束效果很麻烦,比较恶劣没有强制约束的效果的方法(删除不会影响对方,但是还要有关联的关系字段):
1. au = models.integerField()这种不能使用orm提供的级联方法2. au = models.OneToOneField("AuthorDetail",db_constraint=False) db_constraint=False这个属性的作用:取消foreignkey的强制约束效果,和AuthorDetail建立的级联关系,可以继续使用orm给我们提供的关联表查询或操作的各种方法,没有强制约束效果使用级联方法:author.obj.au.birthday 拿到当前表的对象,然后.au级联关系,然后就可以拿到关联表的属性了。
5. 多表关系记录的添加
增加
from django.shortcuts import render,HttpResponse
from app01 import models
def query(request):# 增# 一对一关系的添加# 先创建作者详细信息表记录# ret = models.AuthorDetail.objects.create(# birthday='2000-12-12',# telephone='122',# addr='惠州',# )### models.Author.objects.create(# name='元涛',# age=18,## 第一种写法# # au_id=ret.id, #如果用的是属性名称_id,那么值为关联记录的id值## 第二种写法# au=ret, #如果写属性名称来添加关系数据,那么值为关联记录的模型类对象# )# 一对多(publish表记录是提前加好了)# pub_obj = models.Publish.objects.get(id=1)# models.Book.objects.create(# title='白洁2',# price=10,# publishDate='1980-07-07',## 第一种写法# # publishs=pub_obj, #如果写属性名称来添加关系数据,那么值为关联记录的模型类对象## 第二种写法# publishs_id=2, #如果用的是属性名称_id,那么值为关联记录的id值## )# 多对多# book_obj = models.Book.objects.get(title='白夜行')# author1 = models.Author.objects.get(id=1)# author2 = models.Author.objects.get(id=2)## 第一种写法# book_obj.authors.add(author1,author2)## 第二种写法# book_obj.authors.add(1, 2)# book_obj.authors.add(*[1,2])return HttpRequest('ok')
6. 小提示和小练习
小提示:
1. pycharm默认只能给你创建一个应用,后面的只能用指令操作
2. 在Tools点击Run manage.py Task,这样就可以简单的输入命令了
startapp booksys
3. 应用和项目关联起来,在settings中添加一个应用
4. 自己的应用创建自己的表
5. 如果action什么都没有写,post请求就是忘当前路径上发
6. updata方法只能queryset类型数据调用