首页
壁纸
关于
推荐
战略合作
Google
主题Joe
Search
1
涂鸦设备本地化接入(涂鸦电表)
13 阅读
2
CentOS 定时同步指定文件到ftp
6 阅读
3
laydate输入日期年月日时分,以十分钟为间隔,不需要秒
5 阅读
4
记一次Django_cas_ng数据库migrate错误
5 阅读
5
Centos7 安装python3并配置pip
4 阅读
运维
Windows
Linux
MacOS
Android
vmware
开发
Python
Go
Html
Electron
智家
HomeAssistant
ESPhome
Unraid
群晖
网络相关
登录
Search
标签搜索
运维
Linux
Python
django
智能家居
Nginx
MACos
brew
layui
cas
群晖
nas
zabbix
vim
JDK
sonar
jenkins
Nexus
转发
mysql
Ruike
累计撰写
29
篇文章
累计收到
109
条评论
首页
栏目
运维
Windows
Linux
MacOS
Android
vmware
开发
Python
Go
Html
Electron
智家
HomeAssistant
ESPhome
Unraid
群晖
网络相关
页面
壁纸
关于
推荐
战略合作
Google
主题Joe
搜索到
7
篇与
的结果
2020-05-01
python 判断数据类型
Python 判断数据类型有type和isinstance基本区别在于:type():不会认为子类是父类 isinstance():会认为子类是父类类型 class Color(object): pass class Red(Color): pass print type(Color()) == Color print type(Red()) == Color print isinstance(Red(),Color)执行结果如下:D:\software\Python2.7.13\python.exe PythonStudy/test.py True False True用isinstance判断mongDB中的一些数据类型:字符串、int、long、float - isinstance(data, (int, str, types.LongType, float)) 时间类型 - isinstance(data, datetime.datetime) 布尔类型 - isinstance(data, (bool)) 字典类型 - isinstance(data, (dict)) 数组 - isinstance(data, (list)) unicode - isinstance(data, unicode) mongo obJect - isinstance(data, bson.objectid.ObjectId) 可以引入types模板,获取数据类型: inport types types取值: BooleanType BufferType BuiltinFunctionType BuiltinMethodType ClassType CodeType ComplexType DictProxyType DictType DictionaryType EllipsisType FileType FloatType FrameType FunctionType GeneratorType GetSetDescriptorType InstanceType IntType LambdaType ListType LongType MemberDescriptorType MethodType ModuleType NoneType NotImplementedType ObjectType SliceType StringType StringTypes TracebackType TupleType TypeType UnboundMethodType UnicodeType XRangeType
2020年05月01日
1 阅读
0 评论
0 点赞
2020-04-09
Django templay 配置全局变量
setting.pyTEMPLATES0['context_processors']最后面添加一行:'Tools.context_processors.app_name',如下: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', 'Tools.context_processors.app_name', ], }, }, ]同时,setting.py添加配置:APP_NAME=‘你网站的名称’Tools.context_processors.py#!/usr/bin/env python3 # -*- coding:utf-8 -*- # @Author: Ruike # @Time: 2019-10-20 23:38 # @File: context_processors.py.py # @Project: setting变量前端传递模版 from django.conf import settings # 项目名称 def app_name(request): return {'APP_NAME': settings.APP_NAME}模版引用:{{ APP_NAME }}
2020年04月09日
2 阅读
0 评论
0 点赞
2019-05-14
Django之分页与搜索分页
一、分页代码如下vim views.pyfrom django.core.paginator import Paginator def property_list(request): messages = models.ProdDetail.objects.all() limit = 25 paginator = Paginator(messages, limit) # 按每页25条分页 page = request.GET.get('page', '1') # 默认跳转到第一页 result = paginator.page(page) return render(request, 'lists.html', {'contacts': result})vim lists.html<div class="layui-card-body "> <div class="page"> <div> {% if contacts.has_previous %} <a class="prev" href="?page=1"><<</a> <a class="prev" href="?page={{ contacts.previous_page_number }}">上一页</a> {% else %} <a class="prev"><<第一页</a> {% endif %} <span class="current">第{{ contacts.number }}页/共{{ contacts.paginator.num_pages }}页</span> {% if contacts.has_next %} <a class="next" href="?page={{ contacts.next_page_number }}">下一页</a> <a class="next" href="?page={{ contacts.paginator.num_pages }}">>></a></div> {% else %} <a class="next-off">最后页>></a> {% endif %} </div> </div>2、搜索的分页在进行搜索时,下一页时因为是新的页面,所以搜索参数并没有传到新的页面,导致结果没回传,所以我们需要一个方法来传递搜索参数。代码如下:vim views.pydef property_list(request): # 接受get参数 userid = request.GET.get('userid') name = request.GET.get('name') prodsn = request.GET.get('prodsn') search = {} getmathod = '' if userid: # 模糊搜索 search['user_id__icontains'] = userid # 搜索参数的保存传递 getmathod += ('&userid=%s' % userid) if name: search['name__icontains'] = name getmathod += ('&name=%s' % name) if prodsn: search['s_sn__icontains'] = prodsn getmathod += ('&prodsn=%s' % prodsn) messages = models.ProdDetail.objects.filter(**search) limit = 25 paginator = Paginator(messages, limit) # 按每页25条分页 page = request.GET.get('page', '1') # 默认跳转到第一页 result = paginator.page(page) # 将原来的get请求封装后返回给前端 return render(request, 'lists.html', {'contacts': result, 'getmathod': getmathod})将getmathod传递给前端,加在page href后:=={{ getmathod }}==vim lists.html{% if contacts.has_previous %} <a class="prev" href="?page=1{{ getmathod }}"><<</a> <a class="prev" href="?page={{ contacts.previous_page_number }}{{ getmathod }}">上一页</a> {% else %} <a class="prev"><<第一页</a> {% endif %} <span class="current">第{{ contacts.number }}页/共{{ contacts.paginator.num_pages }}页</span> {% if contacts.has_next %} <a class="next" href="?page={{ contacts.next_page_number }}{{ getmathod }}">下一页</a> <a class="next" href="?page={{ contacts.paginator.num_pages }}{{ getmathod }}">>></a></div> {% else %} <a class="next-off">最后页>></a> {% endif %}
2019年05月14日
3 阅读
0 评论
0 点赞
2019-05-05
Django 学习笔记
一、项目1、创建项目django-admin startproject mysite2、创建应用python manage.py startapp blog3、启动项目python manage.py runserver 80804、目录结构二、路由1、路由配置# vim urls.py import blog.view ... url(r'^welcome', blog.view.welcome), ...2、路由处理vim blog.view.pydef welcome(request): ..... return render(request, 'welcome.html') # welcome.html是templates下的视图文件3、变量传递vim view.pydef welcome(request): ..... return render(request, 'welcome.html',{'abc':times})vim welcome.html... <a> {{ abc }} </a> ...4、路由正则匹配(1) 开头结尾'^admin/$' ^ : 以admin开头$ : 以admin/结尾(2)数字匹配'^admin/[0-9]{4}/$'[0-9]{4} :0~9 4个数字,如2019(3)无名参数'^admin/([0-9]{4})/([0-9]{2})/$'()括号内当无名参数顺序传递给view函数视图函数需要接收两个变量(4)有名参数'^admin/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$'将匹配到的参数以year和month传回,接收需要参数名5、默认参数url(r'index',view.index,{'name':'ruike'})将name='ruike'有名形参传递回视图函数6、路由别名vim urls.pyurl(r'^index', view.index, name='index2')别名传递到视图vim template.index.html<form action={% url "index2" %} methon="post">7、路由分发vim project/urls.py# 将blog的路由分发到blog.urls from django.urls import path, include url(r'^blog/', include('blog.urls')),vim blog/urls.pyfrom django.urls import path import views urlpatterns = [ path('new/$', views.new), ]最终路由/blog/new三、视图模版文件1、变量符 {{ }}(1)变量传递vim view.pydef welcome(request): ..... return render(request, 'welcome.html',{'abc':times})vim welcome.html... <a> {{ abc }} </a> ...2、程序 {% %}(1) for函数vim welcome.html{% for i in url_list %} <tr> <td> i.name </td> <td> i.email </td> <td> i.sex </td> </tr> {% endfor %}3、模版之继承(1)、盒子放置vim base.html ... {% block block_name1 %} {% endblock %} ... {% block block_name2 %} {% endblock %} ...(2)、盒子引用vim hello.html # 必须放在页面文件第一个位置 {% extends 'base.html' %} {% blocl block_name1 %} ...... {% endblock %} {% blocl block_name2 %} ...... {% endblock %} 四、Model1、模型创建生成同步数据库的脚本:python manage.py makemigrations同步数据库: python manage.py migrate注意:在开发过程中,数据库同步误操作之后,难免会遇到后面不能同步成功的情况,解决这个问题的一个简单粗暴方法是把migrations目录下的脚本(除__init__.py之外)全部删掉,再把数据库删掉之后创建一个新的数据库,数据库同步操作再重新做一遍。(1)字段类型:AutoField根据可用ID自动递增。您通常不需要直接使用它; 如果您没有另外指定,主键字段将自动添加到您的模型中。BigAutoField一个64位整数,很像一个AutoField不同之处在于它是保证从适合数字1到9223372036854775807。BinaryFieldclassBinaryField(max_length = None,** options)用于存储原始二进制数据的字段。它可以分配bytes, bytearray或memoryview。默认情况下,BinaryField设置editable为False,在这种情况下,它不能包含在a中ModelForm。BooleanField真/假字段CharField字符串字段,用于小到大的字符串DateField日期DateTimeField日期和时间TimeField时间DecimalField一个固定精度的十进制数,由Python Decimal实例表示。它使用验证输入 DecimalValidator。有两个必需的参数:DecimalField.max_digits¶数字中允许的最大位数。请注意,此数字必须大于或等于decimal_places。DecimalField.decimal_places¶与数字一起存储的小数位数。DurationField用于存储时间段的字段 - 用Python建模 timedelta。在PostgreSQL上使用时,使用interval的数据类型是Oracle,数据类型是。否则使用一微秒。INTERVAL DAY(9) TO SECOND(6)bigintEmailField检查该值是使用一个有效的电子邮件地址FileFieldclassFileField(upload_to = None,max_length = 100,** options)IntegerField整数,无需定义长度PositiveIntegerField正整数TextField大文本GenericIPAddressFieldclassGenericIPAddressField(protocol ='both',unpack_ipv4 = False,** options)IPv4或IPv6地址,采用字符串格式URLFieldUUIDField(2)字段选项:nullnull=True 则数据库字段允许为空。默认为falseblankblank=True,则表单验证将允许输入空值。默认为falsechoices一个可迭代的,用作该字段的选择。每个元组中的第一个元素是要在模型上设置的实际值,第二个元素是人类可读的名称。例如: from django.db import models class Student(models.Model): YN_IN_SCHOOL_CHOICES = [ (0, '是'), (1, '否'), ] #... status = models.CharField( max_length=2, choices=YN_IN_SCHOOL_CHOICES, default=1, )第二个元素是人类可读的名称采用get_FOO_display()来读,比如:get_status_display() ==> "是"db_column用于此字段的数据库列的名称。如果没有给出,Django将使用该字段的名称。如果您的数据库列名是SQL保留字,或者包含Python变量名中不允许的字符 - 特别是连字符 - 那就没问题。Django在幕后引用了列名和表名。db_index如果True,将为此字段创建数据库索引db_tablespace如果此字段已编制索引,则用于此字段索引的数据库表空间的名称。默认值为项目的 DEFAULT_INDEX_TABLESPACE设置(如果已设置)或 db_tablespace模型的设置(如果有)。如果后端不支持索引的表空间,则忽略此选项。default字段的默认值。这可以是值或可调用对象。如果可调用,则每次创建新对象时都会调用它。editable如果False,该字段将不会显示在管理员或任何其他字段中 ModelForm。在模型验证期间也会跳过它们。默认是True。error_messages该error_messages参数允许您覆盖该字段将引发的默认消息。传入一个字典,其中的键与您要覆盖的错误消息相匹配。错误消息键包括null,blank,invalid,invalid_choice, unique,和unique_for_date。在下面的“ 字段类型”部分中为每个字段指定了其他错误消息密钥。help_text使用表单小部件显示的额外“帮助”文本。即使您的字段未在表单上使用,它也对文档很有用。请注意,此值不会在自动生成的表单中进行HTML转义primary_key如果True,此字段是模型的主键。如果没有primary_key=True为模型中的任何字段指定,Django将自动添加一个AutoField来保存主键,因此primary_key=True除非要覆盖默认的主键行为,否则不需要设置任何字段。有关更多信息,请参阅 自动主键字段。primary_key=True暗示null=False和 unique=True。对象上只允许一个主键。主键字段是只读的。如果更改现有对象上的主键值,然后保存它,则将创建一个与旧对象并排的新对象unique如果True,该字段在整个表格中必须是唯一的。unique_for_date将其设置为a的名称DateField或DateTimeField要求此字段对于日期字段的值是唯一的。举例来说,如果你有一个字段title有 unique_for_date="pub_date",那么Django的不允许的两个记录具有相同的入口title和pub_date。unique_for_monthunique_for_year(3)字段关系ForeignKeyclassForeignKey(to,on_delete,** options)ManyToManyFieldclassManyToManyField(to,** options)OneToOneFieldclassOneToOneField(to,on_delete,parent_link = False,** options)2、ORM模型--单表(1).增删改查1).增create方法一from models import Book Book.objects.create( title = "罗宾逊漂流记", price = 1, color = "green", publicsher_id = 4, )方法二from models import Book dicts = { "title" = "罗宾逊漂流记", "price" = 1, "color" = "green", "publicsher_id" = 4, } Book.objects.create(**dicts)2).删deleteBook.objects.filter(id=1).delete()3).改update方法一:先取出后改(全部更改)# 拿到对象 books = Book.objects.get(id = 2) books.name = "天空之城" books.save方法二:效率高(只改name)# 拿到集合 Books.objects.filter(id = 2).update(name = '天空')4).查查询API序号命令说明1fiter(**kwargs)包含所有符合的集合对象2all()包含所有的集合对象3get(**kwargs)返回一个条件匹配的对象,没有或多个都会报错对查询结果再进行处理序号命令说明1exclude(**kwargs)筛选不匹配的条件(反选)2order_by(*key)排序,如order_by('-id')对ID反排序3reverse()对结果进行反向排序4distinct()对结果去重5first()返回第一条记录6last()返回最后一条记录7values(*key)返回对不是对象,而是一个可迭代字典8values_list(*key)返回对不是对象,而是一个元组序列9count返回查询到的对象数量10exists()如果结果包含数据,返回True,否则返回False(2) 神奇的双下划线之单表查询命令涵义filter表示=exclude表示!=querySet.distinct()去重复__exact精确等于 like 'aaa'__iexact精确等于 忽略大小写 ilike 'aaa'__contains包含 like '%aaa%'__icontains包含 忽略大小写 ilike '%aaa%',但是对于sqlite来说,contains的作用效果等同于icontains__gt大于__gte大于等于__lt小于__lte小于等于__in存在于一个list范围内__startswith以...开头__istartswith以...开头 忽略大小写__endswith以...结尾__iendswith以...结尾,忽略大小写__range在...范围内__year日期字段的年份__month日期字段的月份__day日期字段的日__isnull=True/False# 获取id大于1 且 小于10的值 models.Tb1.objects.filter(id__lt=10, id__gt=1) # 获取id等于11、22、33的数据 models.Tb1.objects.filter(id__in=[11, 22, 33]) # in models.Tb1.objects.exclude(id__in=[11, 22, 33]) # 模糊查询 models.Tb1.objects.filter(name__contains="ven") # 模糊查询,大小写不敏感 models.Tb1.objects.filter(name__icontains="ven") # 范围bettwen models.Tb1.objects.filter(id__range=[1, 2]) # 开始于 结束与 startswith,istartswith, endswith, iendswith,3、多表操作(1)一对多一个班级,对应多个学生:班级是1,学生是多ForeignKey在多里1)表的创建class ClassAndGrade(models.Model): grade = models.CharField(max_length=10) classname = models.CharField(max_length=10) class Studen(models.Model): name = models.CharField(max_length=10) age = = models.IntegerField() # 一对多,在数据库键名为 classandgrade_id classandgrade = ForeignKey('ClassAndGrade')2)create有两张方法:通过classandgrade_id插入Sutden.objects.create( name = '张三', age = 12, # _id方法直接赋值 classandgrade_id = 1, )通过班级的对象去插入classes = ClassAndGrade.object.filter(id=1) Sutden.objects.create( name = '张三', age = 12, # 根据对象绑定关系 classandgrade = classes[0], )3)查-正向查找需求:查询学生的班级名称# 取到学生的对象 studen = Sutden.objects.filter(name='张三') # 取到班级的对象 classes = studen.classandgrade # 取到班级名称 classname = classes.classname4)查-反向查找需求:查询某个班级下的所有学生的名字# 取到班级 classes = ClassAndGrade.object.filter(classname='一班') # 取到学生的集合_set studens = classes.studen_set.all() # 取到名字的集合 studensname = sutdens.values('name') 或# __ 查询关联表 studensname = Sutden.objects.filte(classandgrade__classname='一班').values('name')(2)多对多一个学生可以加入多个社团,一个社团可以加入过个学生;一本书可以有多个作者,一个作者可以有多本书,这就是多对多的关系1)使用 ManyToManyField自动创建使用ManyToManyField关键字可以创建 第三张表Book_Authors关联 book与author的关系。from django.db import models class Book(models.Model): # ... authors = models.ManyToManyField(Author) class Author(models.Model): # ... pass但是该方式在第三张表中只能存id和两个外键,如果需要记录额外字段,请用下面半自动的方式2)多对多关系中的额外字段如果您可能希望收集的成员资格,有很多详细信息,例如该人加入该组的日期。对于这些情况,Django允许您指定将用于管理多对多关系的模型。然后,您可以在中间模型上放置额外的字段。中间模型与ManyToManyField使用 through参数关联 以指向将充当中介的模型。对于我们的音乐家示例,代码如下所示:from django.db import models class Person(models.Model): name = models.CharField(max_length=128) def __str__(self): return self.name class Group(models.Model): name = models.CharField(max_length=128) members = models.ManyToManyField(Person, through='Membership') def __str__(self): return self.name class Membership(models.Model): person = models.ForeignKey(Person, on_delete=models.CASCADE) group = models.ForeignKey(Group, on_delete=models.CASCADE) date_joined = models.DateField() invite_reason = models.CharField(max_length=64)设置中介模型时,您需要为多对多关系中涉及的模型明确指定外键。该显式声明定义了两个模型之间的关系。中间模型有一些限制:您的中间模型必须包含源模型的一个和唯一一个外键(Group在我们的示例中将是这样),或者您必须使用显式指定Django应该用于关系的外键ManyToManyField.through_fields。如果您有多个外键through_fields且未指定,则将引发验证错误。类似的限制适用于目标模型的外键(这Person在我们的示例中)。对于通过中介模型与其自身具有多对多关系的模型,允许使用同一模型的两个外键,但是它们将被视为多对多关系的两个(不同)方面。如果有更多的比两个外键虽然,你还必须指定through_fields如上,或验证错误将得到提升。既然您已经设置好ManyToManyField使用中介模型(Membership在本例中为),就可以开始创建一些多对多关系了。您可以通过创建中间模型的实例来做到这一点:3)create>>> ringo = Person.objects.create(name="Ringo Starr") >>> paul = Person.objects.create(name="Paul McCartney") >>> beatles = Group.objects.create(name="The Beatles") >>> m1 = Membership(person=ringo, group=beatles, ... date_joined=date(1962, 8, 16), ... invite_reason="Needed a new drummer.") >>> m1.save() >>> beatles.members.all() <QuerySet [<Person: Ringo Starr>]> >>> ringo.group_set.all() <QuerySet [<Group: The Beatles>]> >>> m2 = Membership.objects.create(person=paul, group=beatles, ... date_joined=date(1960, 8, 1), ... invite_reason="Wanted to form a band.") >>> beatles.members.all() <QuerySet [<Person: Ringo Starr>, <Person: Paul McCartney>]>4)add(),create()或set()只要为任何必填字段指定,您还可以使用add(),create()或set()创建关系through_defaults:beatles.members.add(john, through_defaults={'date_joined': date(1960, 8, 1)}) beatles.members.create(name="George Harrison", through_defaults={'date_joined': date(1960, 8, 1)}) beatles.members.set([john, paul, ringo, george], through_defaults={'date_joined': date(1960, 8, 1)})5)remove()如果中间模型定义的自定义通过表未在该对上强制执行唯一性,从而允许多个值,则该 调用将删除所有中间模型实例:(model1, model2)remove()>>> Membership.objects.create(person=ringo, group=beatles, ... date_joined=date(1968, 9, 4), ... invite_reason="You've been gone for a month and we miss you.") >>> beatles.members.all() <QuerySet [<Person: Ringo Starr>, <Person: Paul McCartney>, <Person: Ringo Starr>]> >>> # This deletes both of the intermediate model instances for Ringo Starr >>> beatles.members.remove(ringo) >>> beatles.members.all() <QuerySet [<Person: Paul McCartney>]>6) clear()该clear() 方法可用于删除实例的所有多对多关系:>>> # Beatles have broken up >>> beatles.members.clear() >>> # Note that this deletes the intermediate model instances >>> Membership.objects.all() <QuerySet []> 建立多对多关系后,就可以发出查询。就像普通的多对多关系一样,您可以使用多对多相关模型的属性进行查询:# Find all the groups with a member whose name starts with 'Paul' >>> Group.objects.filter(members__name__startswith='Paul') <QuerySet [<Group: The Beatles>]>使用中间模型时,还可以查询其属性:# Find all the members of the Beatles that joined after 1 Jan 1961 >>> Person.objects.filter( ... group__name='The Beatles', ... membership__date_joined__gt=date(1961,1,1)) <QuerySet [<Person: Ringo Starr]>如果您需要访问会员的信息,可以直接查询Membership模型:>>> ringos_membership = Membership.objects.get(group=beatles, person=ringo) >>> ringos_membership.date_joined datetime.date(1962, 8, 16) >>> ringos_membership.invite_reason 'Needed a new drummer.' 访问同一信息的另一种方式是通过查询 许多一对多相反的关系从一个 Person对象: >>> ringos_membership = ringo.membership_set.get(group=beatles) >>> ringos_membership.date_joined datetime.date(1962, 8, 16) >>> ringos_membership.invite_reason 'Needed a new drummer.'4、聚合查询与分组查询(1)聚合查询 aggregatefrom django.db.models import Avg,Min,Sum,Max # 统计所有人的平均年龄 Studen.objects.all().aggregate(Avg('age')) # {'age__avg': 14} # 如果需要最大最小值,也可以: Studen.objects.all().aggregate(Max('age'),Min('age'), Avg('age')) # {'age__max':16, 'age__min': 12 } # 如果需要定义结果的key,可以 Studen.objects.all().aggregate(ageavg=Avg('age')) # {'ageavg': 14}(2) 分组查询 annotatefrom django.db.models import Avg,Min,Sum,Max # 统计不同班级的平均年龄 Studen.objects.values('classandgrade__classname').annotate(Avg('age')) # [ # {'classandgrade__classname': '一班', 'age__avg': 14}, # {'classandgrade__classname': '二班', 'age__avg': 15} # ] 5、F查询与Q查询(1)F查询专门对某列 ==数值== 取值需求:对所有人年龄+1逻辑:需先取出每个人的年龄再加回去from django.db.models import F Studen.objects.all().update(age=F('age')+1)(2)Q查询对查询条件多个关键字参数进行封装,从而更好地应用多个查询1.操作符:| 或& 与~ 反2.应用范围:filter()get()exclude()from django.db.models import Q # 查询年龄等于13的学生 models.Studen.objects.filter(Q(age=13)) # 查询男生年龄大于12,或女生年龄大于14 models.Studen.objects.filter( Q(Q(sex='男')&Q(age_gt=12))| Q(Q(sex='女')&Q(age_gt=14)) ) # ~操作符放在前面表示否定,也可允许否定与不否定形式的组合 Q(title__startswith='P') | ~Q(pub_date__year=2005) # Q and也可以如下写 Book.objects.get( Q(title__startswith='P'), Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6)) ) # Q对象可以与关键字参数查询一起使用,不过一定要把Q对象放在关键字参数查询的前面。 # 正确: Book.objects.get( Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6)), title__startswith='P') # 错误: Book.objects.get( question__startswith='P', Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6)))
2019年05月05日
1 阅读
0 评论
0 点赞
2019-05-05
python3 + cas_ng
这两天废了九牛二虎之力完成了python3.5接入cas server, 废话少说,步骤如下:1.基础环境python 3.5.4django 2.0对接的cas server 3.5.2注:cas对外提供的是https python的环境算是比较新的了,所以坑比较多。cas我偷懒了用了个老版本2、django对接cas环境的安装(1)安装python-cas,这个建议下载1.2.0版本以上的1.2.0版本的链接:https://pypi.python.org/pypi/python-cas/1.2.0解压---> python setup.py install(2)安装django_cas_ng 这个建议3.5.8以上,这时候坑就来了3.5.8版本的链接:?https://pypi.python.org/pypi/django-cas-ng然后 解压 ---> python setup.py(3)配置的setting.py,其中AUTHENTICATION_BACKENDS可能没有,需要你自行添加INSTALLED_APPS = ( 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'django_cas_ng', ... ) MIDDLEWARE_CLASSES =( 'django.middleware.common.CommonMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', ... ) AUTHENTICATION_BACKENDS = ( 'django.contrib.auth.backends.ModelBackend', 'django_cas_ng.backends.CASBackend', ) CAS_SERVER_URL="cas server的地址" CAS_REDIRECT_URL="你网站的主页"(4)配置url.py,增加import django_cas_ng.views url(r'^accounts/login$', django_cas_ng.views.login, name='cas_ng_login'), url(r'^accounts/logout$', django_cas_ng.views.logout, name='cas_ng_logout'), url(r'^accounts/callback$', django_cas_ng.views.callback, name='cas_ng_proxy_callback'), (5)配置数据库首先查看你的数据库是否有,下表:auth_groupauth_group_permissionsauth_permissionauth_userauth_user_groupsauth_user_user_permissions要是没有的话请执行:python manage.py makemigrations python manage.py migrate 然后查看是否有:django_cas_ng_proxygrantingticketdjango_cas_ng_sessionticket要是没有的话,请执行:python manage.py makemigrations django_cas_ng python manage.py migrate django_cas_ng(6)访问要是你的cas server 是http的,现在你就可以访问http://django的ip+port/accounts/login,要是转到cas上,就说明你成功了要是你的cas server 是https的,请在django的主机是添加环境变量export REQUESTS_CA_BUNDLE="证书的路径" 这里的证书必须是PEM格式的,否则会报requests.exceptions.SSLError: unknown error (_ssl.c:3165) 如果你的证书使用keytool转换的,请再用下面的命令把之前的证书转换为PEM格式的openssl x509 -inform der -in server.cer -out server.pemaccounts/login 到此配置完毕,你可以访问http://django的ip+port/accounts/login,要是转到cas上,就说明你成功了
2019年05月05日
1 阅读
0 评论
0 点赞
1
2