西维蜀黍

【hexo】使用 AWS s3 作为 hexo 图库

AWS s3

AWS 的对象存储服务。

CloudFront Distribution

CloudFront Distribution 是AWS的内容分发(CDN)使得全球各地都能以最快的速度访问到AWS最近的节点(对于中国,最近的是东京,经测,也已经足够快),并且可绑定或者生产SSL证书。

  ...


【JQuery】获取对象

$("#myELement")    选择id值等于myElement的元素,id值不能重复在文档中只能有一个id值是myElement所以得到的是唯一的元素 
$("div")           选择所有的div标签元素,返回div元素数组 
$(".myClass")      选择使用myClass类的css的所有元素 
$("*")             选择文档中的所有的元素,可以运用多种的选择方式进行联合选择:例如$("#myELement,div,.myclass") 

层叠选择器

$("form input")         选择所有的form元素中的input元素 
$("#main > *")          选择id值为main的所有的子元素 
$("label + input")     选择所有的label元素的下一个input元素节点,经测试选择器返回的是label标签后面直接跟一个input标签的所有input标签元素 
$("#prev ~ div")       同胞选择器,该选择器返回的为id为prev的标签元素的所有的属于同一个父元素的div标签 

基本过滤选择器

$("tr:first")               选择所有tr元素的第一个 
$("tr:last")                选择所有tr元素的最后一个 
$("input:not(:checked) + span")   

属性过滤选择器

$("div[id]")              选择所有含有id属性的div元素 
$("input[name='newsletter']")    选择所有的name属性等于'newsletter'的input元素 
 
$("input[name!='newsletter']") 选择所有的name属性不等于'newsletter'的input元素 
 
$("input[name^='news']")         选择所有的name属性以'news'开头的input元素 
$("input[name$='news']")         选择所有的name属性以'news'结尾的input元素 
$("input[name*='man']")          选择所有的name属性包含'news'的input元素 
 
$("input[id][name$='man']")    可以使用多个属性进行联合选择,该选择器是得到所有的含有id属性并且那么属性以man结尾的元素
  ...


【Python】闭包(Closure)和匿名函数(Anonymous Function)

高阶函数(Higher-order function)

变量可以指向函数

以Python内置的求绝对值的函数abs()为例,调用该函数用以下代码:

>>> abs(-10)
10

但是,如果只写abs呢?

>>> abs
<built-in function abs>

可见,abs(-10)是函数调用,而abs是函数本身。

要获得函数调用结果,我们可以把结果赋值给变量:

>>> x = abs(-10)
>>> x
10

但是,如果把函数本身赋值给变量呢?

>>> f = abs
>>> f
<built-in function abs>

结论:函数本身也可以赋值给变量,即:变量可以指向函数。

如果一个变量指向了一个函数,那么,可否通过该变量来调用这个函数?用代码验证一下:

>>> f = abs
>>> f(-10)
10

成功!说明变量f现在已经指向了abs函数本身。直接调用abs()函数和调用变量f()完全相同。

  ...


【Python】装饰器(Wrapper)

Introduction

每个人都有的内裤主要功能是用来遮羞,但是到了冬天它没法为我们防风御寒,咋办?

我们想到的一个办法就是把内裤改造一下,让它变得更厚更长。这样一来,它不仅有遮羞功能,还能提供保暖。

不过有个问题,这个内裤被我们改造成了长裤后,虽然还有遮羞功能,但本质上它不再是一条真正的内裤了。于是聪明的人们发明长裤,在不影响内裤的前提下,直接把长裤套在了内裤外面,这样内裤还是内裤,有了长裤后宝宝再也不冷了。装饰器就像我们这里说的长裤,在不影响内裤作用的前提下,给我们的身子提供了保暖的功效。

谈装饰器前,还要先要明白一件事,Python 中的函数和 Java、C++不太一样,Python 中的函数可以像普通变量一样当做参数传递给另外一个函数,例如:

def foo():
    print("foo")

def bar(func):
    func()

bar(foo)

回到我们的主题。装饰器本质上是一个 Python 函数或类,它可以让其他函数或类在不需要做任何代码修改的前提下增加额外功能,装饰器的返回值也是一个函数/类对象。

它经常用于有切面需求的场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等场景,装饰器是解决这类问题的绝佳设计。

有了装饰器,我们就可以将大量与函数功能本身无关、但是又相似的代码抽离到装饰器中,并获得重用。概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能。

先来看一个简单例子,虽然实际代码可能比这复杂很多:

def foo():
    print('i am foo')

现在有一个新的需求,希望可以记录下函数的执行日志,于是在代码中添加日志记录代码:

def foo():
    print('i am foo')
    logging.info("foo is running")

如果函数 bar()bar2() 也有类似的需求,怎么做?再写一个 logging 在 bar 函数里?这样就造成大量雷同的代码。为了减少重复代码(同时也就增加了重用性(reusability)),我们可以这样做,重新定义一个新的函数:专门处理日志 ,日志处理完之后再执行真正的业务代码

def use_logging(func):
    logging.warn("%s is running" % func.__name__)
    func()

def foo():
    print('i am foo')

use_logging(foo)

这样做逻辑上是没问题的,功能是实现了,但是我们调用的时候不再是调用真正的业务逻辑 foo 函数,而是换成了 use_logging 函数,这就破坏了原有的代码结构, 即我们不得不每次都要把原来的那个 foo 函数作为参数传递给 use_logging 函数。那么有没有更好的方式的呢?当然有,答案就是装饰器。

  ...


【Django】Django 路由规则

编写urlpatterns

最简单的情况

#urls.py
    from app import views #这里的app是你自己的应用的名字
    from django.urls import path
    urlpatterns = [
                path('index/', views.index, name='index'),
    ]

该方法对应view.py中的函数为:

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


【Django】Django 创建 Django 项目或应用

Install Django

$ pip install django

Creating a project

$ django-admin startproject mysite

Start the Project

$ python manage.py runserver

You’ll see the following output on the command line:

If you want to change the server’s port, pass it as a command-line argument. For instance, this command starts the server on port 8080:

$ python manage.py runserver 8080

If you want to change the server’s IP, pass it along with the port. For example, to listen on all available public IPs (which is useful if you are running Vagrant or want to show off your work on other computers on the network), use:

  ...


【Django】template - 插入 Python 代码

if/else 标签

基本语法格式如下:

{% if condition %}
   ... display
{% endif %}

或者:

{% if condition1 %}
   ... display 1
{% elif condiiton2 %}
   ... display 2
{% else %}
   ... display 3
{% endif %}

根据条件判断是否输出。if/else 支持嵌套。

Note:模板标签中的变量是不需要用 {% raw %}{{ {% endraw %} 来包裹的。

and、or 或not

{% raw %}{% if %}{% endraw %} 标签接受 and , or 或者 not 关键字来对多个变量做判断 ,或者对变量取反(not),例如:

{% if athlete_list and coach_list %}
     athletes 和 coaches 变量都是可用的
{% endif %}

注意,{% raw %}{% if %}{% endraw %} 标签不允许在同一个标签中同时使用 and 和 or ,因为逻辑上可能模糊的,这样的代码是不合法的:

{% if athlete_list and coach_list or cheerleader_list %}

系统不支持用圆括号来组合比较操作。 如果你确实需要用到圆括号来组合表达你的逻辑式,考虑将它移到模板之外处理,然后以模板变量的形式传入结果吧。 或者,仅仅用嵌套的 {% raw %}{% if %}{% endraw %} 标签替换

  ...


【Django】Django ORM - QuerySet 序列化

最完美的方法

解决:

  • ‘dict’ object has no attribute ‘_meta’
  • Queryset is not JSON serializable
users = models.User.objects.values(*USER_FIELDS).filter(**filter)[start_index:start_index + limit]
if type(resp) is not list:
   resp = list(resp)
return HttpResponse(json.dumps(resp, indent=2, cls=DjangoJSONEncoder), content_type="application/json")
  ...


【Django】Django ORM - 查询数据

exclude()

Calling filter() again on a queryset clones it and adds new parameters with an AND operator. Note that multiple keyword parameters can be specified in a single function call.

Conversely, exclude() clones a queryset and adds any new parameters with an AND NOT operator:

>>> queryset = Employee.objects.filter(first_name="Roger", age=27)
>>> queryset2 = queryset.filter(last_name="Jolly")
>>> queryset3 = queryset.exclude(last_name="Jolly")
>>> any(employee.first_name != "Roger" for employee in queryset2)False
>>> any(employee.last_name != "Jolly" for employee in queryset2)False
>>> all(employee.last_name != "Jolly" for employee in queryset3)True

To retrieve all objects in the table with no parameters, use the all() function instead of filter(). all() can also be used to create a clone of an existing queryset (more on this later).

Iterating through querysets exposes the query results as instances of the associated Model.

  ...


【Django】Django ORM - CRUD

Retrieve

Retrieving Objects - get()

To retrieve objects from your database, construct a QuerySet via a Manager on your model class.

A QuerySet represents a collection of objects from your database. It can have zero, one or many filters. Filters narrow down the query results based on the given parameters. In SQL terms, a QuerySet equates to a SELECT statement, and a filter is a limiting clause such as WHERE or LIMIT.

You get a QuerySet by using your model’s Manager. Each model has at least one Manager, and it’s called objects by default. Access it directly via the model class, like so:

# Import the models we created from our "news" app
>>> from news.models import Article, Reporter

>>> Blog.objects
<django.db.models.manager.Manager object at ...>
>>> b = Blog(name='Foo', tagline='Bar')
>>> b.objects
Traceback:
    ...
AttributeError: "Manager isn't accessible via Blog instances."

get() raises MultipleObjectsReturned if more than one object was found. The MultipleObjectsReturned exception is an attribute of the model class.

get() raises a DoesNotExist exception if an object wasn’t found for the given parameters. This exception is an attribute of the model class. Example:

Entry.objects.get(id='foo') # raises Entry.DoesNotExist

The DoesNotExist exception inherits from django.core.exceptions.ObjectDoesNotExist, so you can target multiple DoesNotExist exceptions. Example:

from django.core.exceptions import ObjectDoesNotExist
try:
    e = Entry.objects.get(id=3)
    b = Blog.objects.get(id=1)
except ObjectDoesNotExist:
    print("Either the entry or blog doesn't exist.")
  ...