django基础部分
1.django的安装与执行
- django安装
pip3 install django==1.11.11
-
利用命令行创建django项目 django-admin startproject 项目名
-
利用命令行创建app django-admin startapp app名
,记得注册在settings.py中
-
利用命令行运行项目 python manage.py runserver 127.0.0.1:8000
模板文件配置:
| BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) |
| |
| |
| |
| 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', |
| ], |
| }, |
| }, |
| ] |
静态文件配置:
| STATIC_URL = '/static/' |
| |
| STATICFILES_DIRS = [ |
| os.path.join(BASE_DIR, 'static'), |
| os.path.join(BASE_DIR, 'yingying'), |
| os.path.join(BASE_DIR, 'hpg'), |
| ] |

2.django基础必备三件套
2.1 HttpResponse
| |
| |
| views.py: |
| def login(request): |
| 业务逻辑代码... |
| return HttpResponse('hello world') |
2.2 render
| 除request参数外还接受一个待渲染的模板文件和一个保存具体数据的字典参数。 |
| 将数据填充进模板文件,最后把结果返回给浏览器。(类似于我们上面用到的jinja2) |
| |
| views.py: |
| def login(request): |
| |
| ..... |
| msg = '帅哥你好' |
| return render(request,'xxx.html',{'msg':msg}) |
| |
| templates: |
| login.html: |
| {{msg}} |
2.3 redirect
| 接受一个URL参数,表示跳转到指定的URL。 |
| |
| def index(request): |
| |
| return redirect("/home/") |
3.request的相关属性
- request.method --> 返回的是请求的方法(全大写):GET/POST ...
- request.GET --> 取得是URL里面的参数,类似于字典的数据结构
- request.POST --> post提交的数据,类似于字典的数据结构


4.ORM的使用
ORM |
DB |
类 |
数据表 |
属性 |
字段 |
对象 |
数据行 |
-
先创建一个数据库 create database d1;
-
在django中配置要连接的数据库 settings.py
| DATABASES = { |
| 'default': { |
| 'ENGINE': 'django.db.backends.mysql', |
| 'NAME': 'd1', |
| 'HOST': '127.0.0.1', |
| 'PASSWORD': 'root', |
| 'PORT': 3306, |
| 'USER': 'root', |
| } |
| } |
-
用什么连数据库?
| 利用第三方的包,比如第三方包:pymysql和MySQLdb |
| 告诉Django用pymysql模块代替默认的MySQLdb去连接MySQL数据库 |
| 和settings.py同级的__init__.py文件,写上: |
| import pymysql |
| pymysql.install_as_MySQLdb() |
| |
| |
| 可能上面不行(用这个): |
| import pymysql |
| pymysql.version_info = (1, 4, 13, "final", 0) |
| pymysql.install_as_MySQLdb() |
-
创建一个app django-admin startapp app名
,然后在models中创建类,也就是所谓的表
| from django.db import models |
| |
| |
| |
| class User(models.Model): |
| user = models.CharField(max_length=32) |
| pwd = models.CharField(max_length=12) |
-
执行命令创建表
| 1. python manage.py makemigrations --> 找个小本本把models.py的变更记录一下 |
| 2. python manage.py migrate --> 把上面的变更记录翻译成SQL语句,去数据库执行 |

-
如果需要图形化来进行简单的操纵数据库,可以如图


| 可能连接不成功,在路径后面加入:?serverTimezone=GMT |
| |
| |
5.ORM的增删改查
| from app01 improt models |
| |
| models.User.objects.create(字段=值) |
| |
| |
| models.User.objects.filter(字段=值).delete() |
| |
| |
| |
| obj = models.User.objects.filter(字段=值).first() |
| obj.字段 = 新值 |
| obj.save() |
| |
| |
| models.User.objects.get(id=123) |
| models.User.objects.all() |
| models.User.objects.filter(name='seven') |
| models.User.objects.exclude(name='seven') |
| |
| 例子: |
| views.py: |
| from app01 improt models |
| def login(request): |
| |
| user = request.POST.get('user') |
| pwd = request.POST.get('pwd') |
| if models.User.objects.filter(user=user, pwd=pwd): |
| |
| |
6.Django ORM 常用字段和参数
6.1 常用字段
| 1.AutoField |
| int自增列,必须填入参数 primary_key=True。当model中如果没有自增列,则自动会创建一个列名为id的列。 |
| id = models.AutoField(primary_key=True) |
| |
| 2.IntegerField |
| 一个整数类型,范围在 -2147483648 to 2147483647。 |
| |
| 3.CharField |
| 字符类型,必须提供max_length参数, max_length表示字符长度 |
| name = models.CharField(max_length=32) |
| |
| 4.DateField |
| now = models.DateField() |
| 日期字段,日期格式 YYYY-MM-DD,相当于Python中的datetime.date()实例。 |
| 参数: 看 6.6 |
| auto_now:每次修改时修改为当前日期时间。 |
| auto_now_add:新创建对象时自动添加当前日期时间。 |
| auto_now和auto_now_add和default参数是互斥的,不能同时设置。 |
| |
| 5.DateTimeField |
| now_time = models.DateTimeField() |
| 日期时间字段,格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ],相当于Python中的datetime.datetime()实例 |
6.2 字段类型(争取记忆)
| AutoField(Field) |
| - int自增列,必须填入参数 primary_key=True |
| |
| BigAutoField(AutoField) |
| - bigint自增列,必须填入参数 primary_key=True |
| |
| 注:当model中如果没有自增列,则自动会创建一个列名为id的列 |
| from django.db import models |
| |
| class UserInfo(models.Model): |
| |
| username = models.CharField(max_length=32) |
| |
| class Group(models.Model): |
| |
| nid = models.AutoField(primary_key=True) |
| name = models.CharField(max_length=32) |
| |
| SmallIntegerField(IntegerField): |
| - 小整数 -32768 ~ 32767 |
| |
| PositiveSmallIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField) |
| - 正小整数 0 ~ 32767 |
| IntegerField(Field) |
| - 整数列(有符号的) -2147483648 ~ 2147483647 |
| |
| PositiveIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField) |
| - 正整数 0 ~ 2147483647 |
| |
| BigIntegerField(IntegerField): |
| - 长整型(有符号的) -9223372036854775808 ~ 9223372036854775807 |
| |
| BooleanField(Field) |
| - 布尔值类型 |
| |
| NullBooleanField(Field): |
| - 可以为空的布尔值 |
| |
| CharField(Field) |
| - 字符类型 |
| - 必须提供max_length参数, max_length表示字符长度 |
| |
| TextField(Field) |
| - 文本类型 |
| |
| EmailField(CharField): |
| - 字符串类型,Django Admin以及ModelForm中提供验证机制 |
| |
| IPAddressField(Field) |
| - 字符串类型,Django Admin以及ModelForm中提供验证 IPV4 机制 |
| |
| GenericIPAddressField(Field) |
| - 字符串类型,Django Admin以及ModelForm中提供验证 Ipv4和Ipv6 |
| - 参数: |
| protocol,用于指定Ipv4或Ipv6, 'both',"ipv4","ipv6" |
| unpack_ipv4, 如果指定为True,则输入::ffff:192.0.2.1时候,可解析为192.0.2.1,开启此功能,需要protocol="both" |
| |
| URLField(CharField) |
| - 字符串类型,Django Admin以及ModelForm中提供验证 URL |
| |
| SlugField(CharField) |
| - 字符串类型,Django Admin以及ModelForm中提供验证支持 字母、数字、下划线、连接符(减号) |
| |
| CommaSeparatedIntegerField(CharField) |
| - 字符串类型,格式必须为逗号分割的数字 |
| |
| UUIDField(Field) |
| - 字符串类型,Django Admin以及ModelForm中提供对UUID格式的验证 |
| |
| FilePathField(Field) |
| - 字符串,Django Admin以及ModelForm中提供读取文件夹下文件的功能 |
| - 参数: |
| path, 文件夹路径 |
| match=None, 正则匹配 |
| recursive=False, 递归下面的文件夹 |
| allow_files=True, 允许文件 |
| allow_folders=False, 允许文件夹 |
| |
| FileField(Field) |
| - 字符串,路径保存在数据库,文件上传到指定目录 |
| - 参数: |
| upload_to = "" 上传文件的保存路径 |
| storage = None 存储组件,默认django.core.files.storage.FileSystemStorage |
| |
| ImageField(FileField) |
| - 字符串,路径保存在数据库,文件上传到指定目录 |
| - 参数: |
| upload_to = "" 上传文件的保存路径 |
| storage = None 存储组件,默认django.core.files.storage.FileSystemStorage |
| width_field=None, 上传图片的高度保存的数据库字段名(字符串) |
| height_field=None 上传图片的宽度保存的数据库字段名(字符串) |
| |
| DateTimeField(DateField) |
| - 日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] |
| |
| DateField(DateTimeCheckMixin, Field) |
| - 日期格式 YYYY-MM-DD |
| |
| TimeField(DateTimeCheckMixin, Field) |
| - 时间格式 HH:MM[:ss[.uuuuuu]] |
| |
| DurationField(Field) |
| - 长整数,时间间隔,数据库中按照bigint存储,ORM中获取的值为datetime.timedelta类型 |
| |
| FloatField(Field) |
| - 浮点型 |
| |
| DecimalField(Field) |
| - 10进制小数 |
| - 参数: |
| max_digits,小数总长度 |
| decimal_places,小数位长度 |
| |
| BinaryField(Field) |
| - 二进制类型 |
| |
| 字段合集 |
6.3 自定义字段
-
自定义char字段
| class FixedCharField(models.Field): |
| """ |
| 自定义的char类型的字段类 |
| """ |
| def __init__(self, max_length, *args, **kwargs): |
| super().__init__(max_length=max_length, *args, **kwargs) |
| self.length = max_length |
| |
| def db_type(self, connection): |
| """ |
| 限定生成数据库表的字段类型为char,长度为length指定的值 |
| """ |
| return 'char(%s)' % self.length |
| |
| |
| class Class(models.Model): |
| id = models.AutoField(primary_key=True) |
| title = models.CharField(max_length=25) |
| |
| cname = FixedCharField(max_length=25) |
6.4 字段参数
| null 数据库中字段是否可以为空 |
| db_column 数据库中字段的列名 |
| default 数据库中字段的默认值 |
| primary_key 数据库中字段是否为主键 |
| db_index 数据库中字段是否可以建立索引 |
| unique 数据库中字段是否可以建立唯一索引 |
| unique_for_date 数据库中字段【日期】部分是否可以建立唯一索引 |
| unique_for_month 数据库中字段【月】部分是否可以建立唯一索引 |
| unique_for_year 数据库中字段【年】部分是否可以建立唯一索引 |
| |
| verbose_name Admin中显示的字段名称 |
| blank Admin中是否允许用户输入为空 |
| editable Admin中是否可以编辑 |
| help_text Admin中该字段的提示信息 |
| choices Admin中显示选择框的内容,用不变动的数据放在内存中从而避免跨表操作 |
| 如:gf= models.IntegerField(choices=[(0,'何穗'),(1,'大表姐'),],default=1) |
| |
| error_messages 自定义错误信息(字典类型),从而定制想要显示的错误信息; |
| 字典健:null, blank, invalid, invalid_choice, unique,and unique_for_date |
| 如:{'null':"不能为空.",'invalid':'格式错误'} |
| |
| validators 自定义错误验证(列表类型),从而定制想要的验证规则 |
| from django.core.validatorsimport RegexValidator |
| from django.core.validatorsimport EmailValidator,URLValidator,DecimalValidator,\ |
| MaxLengthValidator,MinLengthValidator,MaxValueValidator,MinValueValidator |
| 如: |
| test= models.CharField( |
| max_length=32, |
| error_messages={ |
| 'c1':'优先错信息1', |
| 'c2':'优先错信息2', |
| 'c3':'优先错信息3', |
| }, |
| validators=[ |
| RegexValidator(regex='root_\d+', message='错误了', code='c1'), |
| RegexValidator(regex='root_112233\d+', message='又错误了', code='c2'), |
| EmailValidator(message='又错误了', code='c3'), ] |
| ) |
-
官网
| class UserInfo(models.Model): |
| nid= models.AutoField(primary_key=True) |
| username= models.CharField(max_length=32) |
| |
| class Meta: |
| |
| db_table= "自定义表名" |
| |
| |
| verbose_name= '个人信息' |
| |
| |
| verbose_name_plural= '所有用户信息' |
| |
| |
| index_together= [ |
| ("pub_date","deadline"), |
| ] |
| |
| |
| unique_together= (("driver","restaurant"),) |
6.6 时间字段独有
| DatetimeField、DateField、TimeField这个三个时间字段,都可以设置如下属性。 |
| |
| auto_now_add |
| 配置auto_now_add=True,创建数据记录的时候会把当前时间添加到数据库。 |
| |
| auto_now |
| 配置上auto_now=True,每次更新数据记录的时候会更新该字段。 |
7.ORM查询操作
| models.py |
| |
| from django.db import models |
| |
| |
| |
| |
| |
| class Publish(models.Model): |
| id = models.AutoField(primary_key=True) |
| name = models.CharField(max_length=32) |
| |
| def __str__(self): |
| return '<Person %s %s>' % (self.id, self.name) |
| |
| |
| class Book(models.Model): |
| id = models.AutoField(primary_key=True) |
| title = models.CharField(max_length=32) |
| price = models.IntegerField(default=25) |
| scale = models.IntegerField(default=50) |
| press = models.ForeignKey(to="Publish", on_delete=models.CASCADE, related_name='book') |
| |
| def __str__(self): |
| return '<Person %s %s>' % (self.id, self.title) |
| |
| |
| class Auther(models.Model): |
| id = models.AutoField(primary_key=True) |
| name = models.CharField(max_length=32) |
| books = models.ManyToManyField(to='Book', related_name='authers') |
| |
| def __str__(self): |
| return '<Person %s %s>' % (self.id, self.name) |
| |
7.1 必知必会13条
- 不懂就看代码 ---》
D:\python项目\mysite\orm\必知必会.py
| <1> all(): 查询所有结果 |
| |
| <2> get(**kwargs): 返回与所给筛选条件相匹配的对象,返回结果有且只有一个,如果符合筛选条件的对象超过一个或者没有都会抛出错误。 |
| |
| <3> filter(**kwargs): 它包含了与所给筛选条件相匹配的对象 |
| |
| <4> exclude(**kwargs): 它包含了与所给筛选条件不匹配的对象 |
| |
| <5> values(*field): 返回一个ValueQuerySet——一个特殊的QuerySet,运行后得到的并不是一系列model的实例化对象,而是一个可迭代的字典序列 |
| |
| <6> values_list(*field): 它与values()非常相似,它返回的是一个元组序列,values返回的是一个字典序列 |
| |
| <7> order_by(*field): 对查询结果排序 |
| |
| <8> reverse(): 对查询结果反向排序,请注意reverse()通常只能在具有已定义顺序的QuerySet上调用(在model类的Meta中指定ordering或调用order_by()方法)。 |
| |
| <9> distinct(): 从返回结果中剔除重复纪录(如果你查询跨越多个表,可能在计算QuerySet时得到重复的结果。此时可以使用distinct(),注意只有在PostgreSQL中支持按字段去重。) |
| |
| <10> count(): 返回数据库中匹配查询(QuerySet)的对象数量。 |
| |
| <11> first(): 返回第一条记录 |
| |
| <12> last(): 返回最后一条记录 |
| |
| <13> exists(): 如果QuerySet包含数据,就返回True,否则返回False |
7.1.1 返回QuerySet对象的方法有
-
all()
-
filter()
-
exclude()
-
order_by()
-
reverse()
-
distinct()
7.1.2 特殊的QuerySet
- values() 返回一个可迭代的字典序列
- values_list() 返回一个可迭代的元祖序列
7.1.3 返回具体对象的
7.1.4 返回布尔值的方法有:
7.1.5 返回数字的方法
7.2 单表查询之神奇的双下划线
| ret = models.Publish.objects.filter(id__gt=2) |
| ret = models.Publish.objects.filter(id__gte=2) |
| |
| ret = models.Publish.objects.filter(id__lt=2) |
| ret = models.Publish.objects.filter(id__lte=2) |
| |
| ret = models.Publish.objects.filter(id__in=[1, 2, 3]) |
| |
| ret = models.Publish.objects.filter(id__range=[1, 3]) |
| ret = models.Publish.objects.filter(id__gte=1, id__lte=3) |
| |
| ret = models.Publish.objects.filter(name__contains='e') |
| ret = models.Publish.objects.filter(name__icontains='e') |
| |
| ret = models.Publish.objects.filter(name__startswith='e') |
| ret = models.Publish.objects.filter(name__istartswith='e') |
| |
| ret = models.Publish.objects.filter(name__endswith='x') |
| ret = models.Publish.objects.filter(name__iendswith='x') |
7.2 聚合和分组
7.2.1 聚合
aggregate()
是QuerySet
的一个终止子句,放在最后
| from django.db.models import Sum, Avg, Max, Min, Count |
| ret = models.Book.objects.aggregate(Max('price')) --> 查询出书籍表中价格最大的数据 |
| print(ret) --> {'price__max': 70} |
| |
| ret = models.Book.objects.aggregate(别名=Max('price')) |
| |
| ret = models.Book.objects.aggregate(max=Sum('price'), min=Min('price'), avg=Avg('price')) |
| print(ret) --> {'max': 328, 'min': 25, 'avg': 46.8571} |
| ret = models.Book.objects.aggregate(最大值=Max('price')) |
| print(ret) ---> {'最大值': 70} |
| |
| '其它的聚合函数用法一致' |
7.2.2 分组
- 建议可以重新看一下sql的分组
- 记得!!!分组后别的字段直接用会使用不了,只能使用分组字段,别的字段要使用聚合函数才能使用
| |
| ret = models.Publish.objects.annotate(avg=Avg('book__price')) |
| print(ret) |
| 'QuerySet [<Publish: <Person 1 清华出版社>>, <Publish: <Person 4 江苏出版社>>, <Publish: <Person 3 北大出版社>>, <Publish: <Person 2 同济出版社>>, <Publish: <Person 5 南京出版社>>, <Publish: <Person 6 上海交通出版社>>]>' |
| |
| print(ret.values()) |
| {'id': 1, 'name': '清华出版社', 'avg': 48.0} |
| {'id': 4, 'name': '江苏出版社', 'avg': 43.0} |
| {'id': 3, 'name': '北大出版社', 'avg': 45.0} |
| {'id': 2, 'name': '同济出版社', 'avg': None} |
| {'id': 5, 'name': '南京出版社', 'avg': None} |
| {'id': 6, 'name': '上海交通出版社', 'avg': None} |
| |
| |
| |
| ret = models.Book.objects.values('press__name').annotate(avg=Avg('price')) |
| |
| sql: select press__name,avg('prince') from Book group by press__name |
| print(ret) |
| |
| <QuerySet [{'press__name': '清华出版社', 'avg': 48.0}, {'press__name': '江苏出版社', 'avg': 43.0}, {'press__name': '北大出版社', 'avg': 45.0}]> |
| |
| |
| ret = models.Book.objects.values('press__name').annotate(avg=Avg('price'), max=Max('scale')) |
| print(ret) |
| <QuerySet [{'press__name': '清华出版社', 'avg': 48.0, 'max': 120}, {'press__name': '江苏出版社', 'avg': 43.0, 'max': 58}, {'press__name': '北大出版社', 'avg': 45.0, 'max': 110}]> |
| |
| |
| ret = models.Book.objects.annotate(author_num=Count("authers")).filter(author_num__gt=1) |
| print(ret) <QuerySet [<Book: <Person 2 大主宰>>]> |
| |
| |
| sql: select * from book group by book.id having (author_num/Count("authers") > 1 |
| |
| |
| |
| |
| LOGGING = { |
| 'version': 1, |
| 'disable_existing_loggers': False, |
| 'handlers': { |
| 'console':{ |
| 'level':'DEBUG', |
| 'class':'logging.StreamHandler', |
| }, |
| }, |
| 'loggers': { |
| 'django.db.backends': { |
| 'handlers': ['console'], |
| 'propagate': True, |
| 'level':'DEBUG', |
| }, |
| } |
| } |
7.3 F和Q查询
| from django.db.models import F, Q |
7.3.1 F查询
| |
| ret = models.Book.objects.filter(price__gt=F('scale')) |
| |
| models.Book.objects.all().update(scale=F('scale') * 2) |
7.3.2 Q查询
| |
| ret = models.Book.objects.filter(price__gt=25, price__lt=52) |
| |
| ret = models.Book.objects.filter(Q(price__gt=25) | Q(scale__lt=92)) |
| |
| ret = models.Book.objects.filter(Q(price__gt=25) & Q(scale__lt=92)) |
| print(ret) |
7.4 事务
| |
| |
| try: |
| from django.db import transaction |
| |
| with transaction.atomic(): |
| new_publisher = models.Publisher.objects.create(name="火星出版社1") |
| new_publisher = models.Publisher.objects.create(name="火星出版社1") |
| int('1sss') |
| new_publisher = models.Publisher.objects.create(name="火星出版社1") |
| new_publisher = models.Publisher.objects.create(name="火星出版社1") |
| |
| except Exception as e: |
| print(str(e)) |
8.关系字段
8.1 ForeignKey字段参数及查询
- to
要关联的表
- to_field
设置要关联表的字段
- related_name
反向操作时,使用的字段名,用于代替原反向查询时的'表名_set'
- 对于ForeignKey对象,clear()和remove()方法仅在null=True时存在。
| |
| class Publish(models.Model): |
| id = models.AutoField(primary_key=True) |
| name = models.CharField(max_length=32) |
| |
| |
| class Book(models.Model): |
| id = models.AutoField(primary_key=True) |
| title = models.CharField(max_length=32) |
| press = models.ForeignKey(to="Publish", on_delete=models.CASCADE) |
-
当我们要查询某个出版社关联的所有书籍(反向查询)时,我们会这么写:
| |
| models.Publish.objects.first().book_set |
| obj = models.Publish.objects.first().book_set.all() |
-
当我们在ForeignKey字段中添加了参数 related_name 后:
| class Book(models.Model): |
| id = models.AutoField(primary_key=True) |
| title = models.CharField(max_length=32) |
| press = models.ForeignKey(to="Publish", on_delete=models.CASCADE, related_name='book') |
-
当我们要查询某个班级关联的所有学生(反向查询)时,我们会这么写:
| models.Publish.objects.first().book.all() |
| book_obj.press --> 拿到的是一个和我这本书关联的出版社对象 |
| book_obj.press_id --> 数据库中实际存的字段值 |
8.2 ManyToManyField
8.2.1 自己创建第三张表
| class Book(models.Model): |
| id = models.AutoField(primary_key=True) |
| title = models.CharField(max_length=32) |
| press = models.ForeignKey(to="Publish", on_delete=models.CASCADE) |
| |
| |
| class Author(models.Model): |
| id = models.AutoField(primary_key=True) |
| name = models.CharField(max_length=32) |
| |
| |
| |
| class Author2Book(models.Model): |
| id = models.AutoField(primary_key=True) |
| author = models.ForeignKey(to='Author', on_delete=models.CASCADE) |
| book = models.ForeignKey(to='Book', on_delete=models.CASCADE) |
| |
8.2.2 通过系统创建第三张表
| class Book(models.Model): |
| id = models.AutoField(primary_key=True) |
| title = models.CharField(max_length=32) |
| press = models.ForeignKey(to="Publish", on_delete=models.CASCADE) |
| |
| |
| class Author(models.Model): |
| id = models.AutoField(primary_key=True) |
| name = models.CharField(max_length=32) |
| books = models.ManyToManyField(to='Book', related_name='authors') |

8.2.3 第三种.....(待补充)
8.2.4 多对多操作
| 1. 查询 该怎么查就怎么查,不要想着第三张表,它就是一个对应关系而已,add(id1,id2,..)和set([id1,id2,..])就是为了设置对应关系 |
| |
| author_obj.books --> 得到的是一个django封装的管理对象,管理作者与书籍之间的关系 |
| author_obj.books.all() --> 通过这个管理对象我们可以拿到所有的书籍对象 |
| |
| models.Auther.objects.get(id=1).books.add(1, 2) |
| models.Auther.objects.get(id=1).books.set([1, 2]) |
| models.Auther.objects.get(id=1).books.remove(1, 2) |
| models.Auther.objects.get(id=1).books.clear() |
| |
| authors = models.Author.objects.all() |
| print(authors.filter(id=2).first().books.all())----⬇----- |
| <QuerySet [<Book: Book object>, <Book: Book object>, <Book: Book object>]> |
| |
| authors = models.Author.objects.all() |
| print(authors.filter(id=2).first().books.filter(id__gt=3).values()) |
| <QuerySet [{'id': 7, 'title': '傲世九重天', 'press_id': 2}]> |
| 2. 添加 |
| 1. add() |
| book_ids = request.POST.getlist('books') |
| author_name = request.POST.get('author_name') |
| author_obj = models.Author.object.create(name=author_name) |
| author_obj.books.add(*book_ids) |
| author_obj.books.add(*book_obj_list) |
| 3. 删除 |
| obj.delete() |
| 4. 编辑 |
| 1. 模板语言中 |
| {% if book in author.books.all %} |
| 2. ORM编辑多对多 |
| 1. 不能直接操作第三张关系表 |
| 2. 借助ORM给提供的方法 |
| 1. all() |
| 2. add(id1,id2) |
| 3. set([id1, id2]) |
| 4. clear() |
| 5. remove() |
| |
9.django上传文件示例
| |
| <form action="" method="post" enctype="multipart/form-data"> |
| <lable>上传文件</lable> |
| <input type="file" name="file_name"> |
| <br> |
| <input type="submit"> |
| </form> |
| |
| |
| |
| file_obj = request.FILES.get('file_name') |
| print(file_obj)---> <class 'django.core.files.uploadedfile.InMemoryUploadedFile'> |
| file_name = file_obj.name |
| with open(file_name, 'wb') as f: |
| for line in file_obj: |
| f.write(line) |
| |
| from django.conf import settings |
| if os.path.exists(os.path.join(settings.BASE_DIR, file_name)): |
| 业务逻辑..... |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 【.NET】调用本地 Deepseek 模型
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
· DeepSeek “源神”启动!「GitHub 热点速览」
· 上周热点回顾(2.17-2.23)