markdown [jQuery - css()方法]#学习笔记#Web编程#jQuery

[jQuery - css()方法]#学习笔记#Web编程#jQuery

jQuery - css .md
# [jQuery - css() 方法]#学习笔记 #Web编程 #jQuery

## **学习笔记**

### jQuery `css()` 方法

`css()` 方法设置或返回被选元素的一个或多个样式属性。

---

### 返回 CSS 属性

如需返回指定的 CSS 属性的值,请使用如下语法:

```js
css("propertyname");
```

下面的例子将返回首个匹配元素的 background-color 值:  
实例

```js
$("p").css("background-color");
```

---

### 设置 CSS 属性

如需设置指定的 CSS 属性,请使用如下语法:

```js
css("propertyname", "value");
```

下面的例子将为所有匹配元素设置 background-color 值:  
实例

```js
$("p").css("background-color", "yellow");
```

---

### 设置多个 CSS 属性

如需设置多个 CSS 属性,请使用如下语法:

```js
css({"propertyname":"value","propertyname":"value",...});
```

下面的例子将为所有匹配元素设置 background-color 和 font-size:  
实例

```js
$("p").css({ "background-color": "yellow", "font-size": "200%" });
```

markdown [Django模板]#学习笔记#Web编程#Django

[Django模板]#学习笔记#Web编程#Django

Django.md
# [Django 模板]#学习笔记 #Web编程 #Django

## **学习笔记**

### Django Template

- 1.简单例子

  index.html

  > ```django
  > <h1>{{ hello }}</h1>
  > ```

  views.py

  > ```python
  > from django.shortcuts import render,redirect,HttpResponse
  > def hello(request):
  >   context={}
  >      context['hello'] = 'Hello World!'
  >   return render(request, 'hello.html', context)
  > ```

  urls.py

  > ```python
  > urlpatterns = [
  >   url(r'^admin/', admin.site.urls),
  >   url(r'^hello/', views.index),
  > ]
  > ```

- 2.模板语法~变量

  views.py

  > ```python
  > def index(request):
  >   import datetime
  >   s="hello"
  >   l=[111,222,333]    # 列表
  >   dic={"name":"yuan","age":18}  # 字典
  >   date = datetime.date(1993, 5, 2)   # 日期对象
  >
  >   class Person(object):
  >      def __init__(self,name):
  >         self.name=name
  >
  >   person_yuan=Person("yuan")  # 自定义类对象
  >   person_egon=Person("egon")
  >   person_alex=Person("alex")
  >
  >   person_list=[person_yuan,person_egon,person_alex]
  >
  >
  >   return render(request,"index.html",{"l":l,"dic":dic,"date":date,"person_list":person_list})
  > ```

  在 template 中的变量形式:

  > ```django
  > <h4>{{s}}</h4>
  > <h4>列表:{{ l.0 }}</h4>
  > <h4>列表:{{ l.2 }}</h4>
  > <h4>字典:{{ dic.name }}</h4>
  > <h4>日期:{{ date.year }}</h4>
  > <h4>类对象列表:{{ person_list.0.name }}</h4>
  > ```

- 3.模板之过滤器  
   语法:`{{obj|filter__name:param}}`  
   default:如果一个变量是 false 或者为空,使用给定的默认值。否则,使用变量的值。例如:`{{ value|default:"nothing" }}`  
   length:返回值的长度。它对字符串和列表都起作用。例如:`{{ value|length }}`  
   filesizeformat:将值格式化为一个 “人类可读的” 文件尺寸 (例如 '13 KB', '4.1 MB', '102 bytes', 等等)。例如:`{{ value|filesizeformat }}`  
   date:将值按照给定的方式格式化。`{{ value|date:"Y-m-d" }}`   
   safe:Django 的模板中会对 HTML 标签和 JS 等语法标签进行自动转义,原因显而易见,这样是为了安全。但是有的时候我们可能不希望这些 HTML 元素被转义,比如我们做一个内容管理系统,后台添加的文章中是经过修饰的,这些修饰可能是通过一个类似于 FCKeditor 编辑加注了 HTML 修饰符的文本,如果自动转义的话显示的就是保护 HTML 标签的源文件。为了在 Django 中关闭 HTML 的自动转义有两种方式,如果是一个单独的变量我们可以通过过滤器“|safe”的方式告诉 Django 这段代码是安全的不必转义。比如:

  > ```django
  > value="<a href="">点击</a>"
  >     {{ value|safe}}
  >
  > ```

- 4.模板之标签

  for 标签:遍历每一个元素, 语法:

  > ```django
  > {% for person in person_list %}
  > <p>{{ person.name }}</p>
  > {% endfor %}
  > ```

  for...empty 标签:for 标签带有一个可选的`{% empty %}` 从句,以便在给出的组是空的或者没有被找到时,可以有所操作。

  > ```django
  > {% for person in person_list %}
  >  <p>{{ person.name }}</p>
  >
  > {% empty %}
  >  <p>sorry,no person here</p>
  > {% endfor %}
  > ```

  if 标签:`{% if %}`会对一个变量求值,如果它的值是“True”(存在、不为空、且不是 boolean 类型的 false 值),对应的内容块会输出。

  > ```django
  > {% if num > 100 or num < 0 %}
  >     <p>无效</p>
  > {% elif num > 80 and num < 100 %}
  >     <p>优秀</p>
  > {% else %}
  >     <p>凑活吧</p>
  > {% endif %}
  > ```

  with 标签:使用一个简单地名字缓存一个复杂的变量,当你需要使用一个“昂贵的”方法(比如访问数据库)很多次的时候是非常有用的

  > ```django
  > {% with total=business.employees.count %}
  >     {{ total }} employee{{ total|pluralize }}
  > {% endwith %}
  > ```

- 5.自定义标签和过滤器  
   1> 在 settings 中的 INSTALLED_APPS 配置当前 app,不然 django 无法找到自定义的 simple_tag.  
   2> 在 app 中创建 templatetags 模块(模块名只能是 templatetags)  
   3> 创建任意 .py 文件,如:my_tags.py

      > ```python
      > from django import template
      > from django.utils.safestring import mark_safe
      >
      > register = template.Library() #register的名字是固定的,不可改变
      > #以上内容是固定格式。
      >
      > @register.filter #定义一个过滤器
      >
      > def filter_multi(x,y): #实现一个简单的乘法函数 <br> return x * y<br><br>
      >
      > @register.simple_tag #定义一个标签
      >
      > def multi(x,y): <br> return x * y
      >```

  4> 在使用自定义 simple_tag 和 filter 的 html 文件中导入之前创建的 my_tags.py

  `{% load my_tags %}`

  5> 使用 simple_tag 和 filter(如何调用)

  `num=10`

  `{{ num|filter_multi:2 }}` #经过调用得:20

  注意:filter 可以用在 if 等语句后,simple_tag 不可以。filter 只能接收两个参数。

- 6.模板继承  
   Django 模版引擎中最强大也是最复杂的部分就是模版继承,模板继承简单理解为通过继承的方法实现模板(base.html)复用。  
   简单的例子:以下文件 base.html 为模板文件,文件中 {% block mainbody %} {% endblock %} 内需要补充自己需要的内容,子模版可能会覆盖掉模版中的这些位置。

      > ```django
      > <!DOCTYPE html>
      > <html>
      > <head>
      > <meta charset="utf-8">
      > <title></title>
      > </head> > <body>
      > <h1>Hello World!</h1>
      > {% block mainbody %} >
      > {% endblock %} > </body>
      > </html>
      > ```

      下面的文件为继承base.html
      > ```django
      >  {% extends "base.html" %}
      >
      >  {% block mainbody %}<p>继承了 base.html 文件</p>
      >  {% endblock %}
      > ```

markdown [Django模型]#学习笔记#Web编程#Django

[Django模型]#学习笔记#Web编程#Django

Django.md
# [Django 模型]#学习笔记 #Web编程 #Django

## **学习笔记**

模型是关于您的数据的单一的、确定的信息来源。它包含您存储的数据的基本字段和行为。通常,每个模型映射到单个数据库表。

### 基础知识:

- 每个模型都是一个 Python 的类,这些类继承 `django.db.models.Model`
- 模型类的每个属性都相当于一个数据库的字段。
- 综上诉说,Django 给你一个自动生成访问数据库的 API;请参阅 Making queries。

#### 简单的例子

这个样例模型定义了一个 Person, 其拥有 first_name 和 last_name:

```python
from django.db import models

class Person(models.Model):
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=30)
```

**firstname** 和 **lastname** 是模型的字段。每个字段都被指定为 class 属性,每个属性映射到数据库列。  
上面的 Person 模型会创建一个这样的数据库表:

```SQL
CREATE TABLE myapp_person (
    "id" serial NOT NULL PRIMARY KEY,
    "first_name" varchar(30) NOT NULL,
    "last_name" varchar(30) NOT NULL
);
```

一些技术上的说明:

- 该表的名称 “myapp_person” 是自动从某些模型元数据中派生出来,但可以被改写。有关更多详细信息,请参阅:表命名。
- 一个 `id` 字段会被自动添加,但是这种行为可以被改写。请参阅:默认主键字段。
- The `CREATE TABLE` SQL in this example is formatted using PostgreSQL syntax, but it's worth noting Django uses SQL tailored to the database backend specified in your settings file.

### 使用模型

一旦你定义了你的模型,你需要告诉 Django 你将会使用这些模型。通过编辑你的设置文件和改变 **INSTALLED_APPS** 设置来添加包含你的 **models.py** 的模块的名称来实现这一点。  
例如,如果您的应用程序的模型存在于模块**myapp.models**(为应用程序创建的包结构 **manage.py startapp** 脚本),INSTALLED_APPS\*\* 应该阅读部分内容:

```python
 INSTALLED_APPS = [
    #...
    'myapp',
    #...
]
```

当你添加新的 APP 到 **INSTALLED_APPS**, 去报先执行**manage.py migrate**,有时候需要限制性 **manage.py makemigrations**.

### 字段

模型中最重要的部分——以及模型中唯一需要的部分——是它定义的数据库字段列表。字段由 class 属性指定。注意不要选择与模型 API 冲突的字段名,如`clean`, `save` 或者 `delete`.  
例子

```python
from django.db import models

class Musician(models.Model):
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)
    instrument = models.CharField(max_length=100)

class Album(models.Model):
     artist = models.ForeignKey(Musician, on_delete=models.CASCADE)
    name = models.CharField(max_length=100)
    release_date = models.DateField()
    num_stars = models.IntegerField()
```

### 字段类型

模型中的每个字段都应该是适当字段类的一个实例。Django 使用`field`类类型来确定一些事情:

- 列类型,它告诉数据库要存储什么样的数据(例如 INTEGER、VARCHAR、TEXT)。
- 默认的 HTML 小部件在呈现表单字段时使用(例如:`<input type="text">,<select>`)。
- 在 Django 的管理员和自动生成的表单中使用的最小验证需求。

Django 配备了数十种内置的字段类型;您可以在模型字段引用中找到完整的列表。如果 Django 的内置函数不奏效,您可以轻松地编写自己的字段;参见编写定制模型字段。

### 字段选项

每个字段都接受一组特定于字段的参数(在模型字段引用中记录)。例如,**CharField**(及其子类)需要一个 `max_length` 参数,该参数指定用于存储数据的`VARCHAR` 数据库字段的大小。  
对于所有字段类型,也有一组通用的参数。都是可选的。它们在参考文献中得到了充分的解释,但这里有一个对最常用的解释的快速总结:  
**null**
如果是 True,Django 会将空置的值存储为 NULL。默认是 False。  
**blank**  
如果是 True,这个字段是空白的。默认是 False。  
注意,这与 null 不同。null 与数据库相关,而 blank 则是与验证相关的。如果一个字段有 **blank=True** ,表单验证就允许输入空值。如果一个字段有**blank=False** ,则需要字段。  
**choices**  
2 元组的可迭代(例如,列表或元组),用作此字段的选项。如果给出了这个,则默认表单小部件将是一个选择框而不是标准文本字段,并将限制对给定选项的选择。  
选择列表如下:

```python
YEAR_IN_SCHOOL_CHOICES = (
    ('FR', 'Freshman'),
    ('SO', 'Sophomore'),
    ('JR', 'Junior'),
    ('SR', 'Senior'),
    ('GR', 'Graduate'),
)
```

每个元组中的第一个元素是储存在数据库中的值。第二个元素由 field 的 form 小部件显示。  
给定一个模型实例,可以使用 `get_FOO_display()`方法访问带有选择的字段的显示值。例如:

```python
from django.db import models

class Person(models.Model):
    SHIRT_SIZES = (
        ('S', 'Small'),
        ('M', 'Medium'),
        ('L', 'Large'),
    )
    name = models.CharField(max_length=60)
    shirt_size = models.CharField(max_length=1, choices=SHIRT_SIZES)
```

如果将 models 加载到 admin 后台,显示如下:  
![models](https://upload-images.jianshu.io/upload_images/12747273-bb474878ab513787.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/833)
**default**  
字段的默认值。这可以是一个值或者一个可调用的对象。如果每次创建新对象时都将调用 callable。  
**help_text**
额外的“帮助”文本将显示在 form 小部件中。即使你的字段没有在表单上使用,它对文档也很有用。

```python
name = models.CharField(max_length=60, default=None, help_text="个人姓名")
```

![help_text](https://upload-images.jianshu.io/upload_images/12747273-1de196828faa04fe.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/778)
**primary_key**  
如果 True,此字段是模型的主键  
如果你没有指定你的模型中的任何字段的 primarykey=True,Django 会自动添加 IntegerField 来保存主键,所以除非你想要覆盖默认的主键行为,否则你不需要在任何字段上设置 primarykey=True。更多信息,请参见自动主键字段。  
主键字段是只读的。如果您将主键的值更改为现存对象,然后保存它,那么将会在旧物件旁边创建一个新物件。例如:

```python
from django.db import models

class Fruit(models.Model):
    name = models.CharField(max_length=100, primary_key=True)
```

**unique**  
如果是真的,这个字段必须在整个表中是唯一的。

### 自动主键字段

在默认情况下,Django 提供了以下字段:

```python
id = models.AutoField(primary_key=True)
```

这是一个自动递增的主键。  
如果您想要指定一个定制的主键,请在您的一个字段中指定 primarykey=True。如果 Django 看到你已经明确地设置了字段。主键,它不会添加自动 id 列。  
每个模型只需要一个字段来拥有 primarykey=True(要么显式声明,要么自动添加)。

### 详细字段名称

除了和 之外 ForeignKey, 每个字段类型都采用可选的第一个位置参数 - 一个详细的名称。如果没有给出详细名称,Django 将使用字段的属性名称自动创建它,将下划线转换为空格。  
`ManyToManyFieldOneToOneField`

- 在此示例中,详细名称为:`"person's first name"`

```python
first_name = models.CharField("person's first name", max_length=30)
```

![person's](https://upload-images.jianshu.io/upload_images/12747273-c72f38ef24f60c23.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/765)

- 在此示例中,详细名称为:`"first name"`

```python
first_name = models.CharField(max_length=30)
```

`ForeignKey`, `ManyToManyField` and `OneToOneField` 都要求第一个参数是一个模型类,所以使用**verbosename**关键字参数:

```python
poll = models.ForeignKey(
    Poll,
    on_delete=models.CASCADE,
    verbose_name="the related poll",
)
sites = models.ManyToManyField(Site, verbose_name="list of sites")
place = models.OneToOneField(
    Place,
    on_delete=models.CASCADE,
    verbose_name="related place",
)
```

公约并不是要利用**verbose_name**的第一个字母。Django 会自动将第一个字母大写。

### 关联关系

显然,关系数据库的功能在于将表相互关联起来。Django 提供了定义三种最常见的数据库关系类型的方法:多对一、多对多和一对一。

#### 多对一

要定义多对一关系,请使用`django.db.models.ForeignKey`。您可以像使用任何其他 Field 类型一样使用它:将其包含为模型的类属性。  
`ForeignKey` 需要一个位置参数:模型相关的类。  
例如,如果一个“汽车”模型有一个“制造商”——也就是说,“制造商”生产多辆汽车,但每辆车都只有一个“制造商”——使用以下定义:

```python
from django.db import models

class Manufacturer(models.Model):
    # ...
    pass

class Car(models.Model):
    manufacturer = models.ForeignKey(Manufacturer, on_delete=models.CASCADE)
    # ...
```

#### 多对多

要定义多对多关系,请使用 `ManyToManyField`。您可以像使用任何其他 Field 类型一样使用它 :将其包含为模型的类属性。  
`ManyToManyField` 需要一个位置参数:模型相关的类。  
例如,如果一个“pizza”有多个“topping”的对象——也就是说,“topping”可以在多个 pizza 上,每个“pizza”都有多种 topping——以下是你如何表示:

```python
class Topping(models.Model):
    # ...
    pass

class Pizza(models.Model):
    # ...
    toppings = models.ManyToManyField(Topping)</pre>
```

#### 多对多关系中的额外字段

当您只处理简单的多对多关系时,例如混合和匹配比萨饼和浇头,ManyToManyField 您只需要一个标准 。但是,有时您可能需要将数据与两个模型之间的关系相关联。  
例如,考虑应用程序跟踪音乐家所属的音乐组的情况。一个人与他们所属的团体之间存在多对多的关系,因此您可以使用`aManyToManyField`来表示这种关系。但是,您可能希望收集的成员资格有很多详细信息,例如此人加入该组的日期。  
对于这些情况,Django 允许您指定将用于管理多对多关系的模型。然后,您可以在中间模型上添加额外的字段。中间模型与`ManyToManyField`使用 `through`参数指向将充当中介的模型相关联 。对于我们的音乐家示例,代码看起来像这样:

```python
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`如上,或验证错误将得到提升。
- 在使用中间模型定义从模型到自身的多对多关系时,必须使用 `symmetrical=False`(请参阅 模型字段引用)。

现在您已经设置了`ManyToManyField`使用中间模型(Membership 在本例中),您已准备好开始创建一些多对多关系。您可以通过创建中间模型的实例来完成此操作:  
![manytomanyfield](https://upload-images.jianshu.io/upload_images/12747273-73f844cd1185af0e.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/905)

#### 一对一

定义一对一, use `OneToOneField`. 您可以像任何其他“字段”类型一样使用它:将其包含为模型的类属性。  
当该对象以某种方式“扩展”另一个对象时,这在对象的主键上是最有用的。  
`OneToOneField` 需要一个位置参数:模型相关的类。  
例如,如果您正在构建“地点”数据库,您将在数据库中构建非常标准的内容,例如地址,电话号码等。然后,如果你想在这些地方建立一个餐馆数据库,而不是重复自己并在`Restaurant`模型中复制这些字段,你可以做`Restaurant`一个`OneToOneField`to `Place`(因为一个餐馆“是一个”地方;事实上,处理这通常使用 继承,它涉及隐式的一对一关系)。  
与此同时`ForeignKey`,可以定义**递归关系**,并且可以对尚未定义的模型进行**引用**。

### 跨文件的模型

将模型与另一个应用程序中的模型相关联是完全可以的。为此,请在定义模型的文件顶部导入相关模型。然后,只需在需要的地方引用其他模型类。例如:

```python
from django.db import models
from geography.models import ZipCode

class Restaurant(models.Model):
    # ...
    zip_code = models.ForeignKey(
        ZipCode,
        on_delete=models.SET_NULL,
        blank=True,
        null=True,
    )
```

### 字段名称限制

django 对模型字段名称只有两个限制:  
1.字段名称不能是 Python 保留字,因为这会导致 Python 语法错误。例如:

```python
class Example(models.Model):
   pass = models.IntegerField() # 'pass' is a reserved word!
```

2.由于 Django 的查询查找语法的工作方式,字段名称不能在一行中包含多个下划线。例如:

```python
class Example(models.Model):
  foo__bar = models.IntegerField() # 'foo__bar' has two underscores!
```

但是,这些限制可以解决,因为您的字段名称不一定必须与您的数据库列名称匹配。请参阅 db_column 选项。  
SQL 保留字(例如 join,where 或 select)被允许作为模型字段名称,因为 Django 会转义每个基础 SQL 查询中的所有数据库表名和列名。它使用特定数据库引擎的引用语法。

### Meta 选项

使用内部提供模型元数据,如下所示:class Meta

```python
class Ox(models.Model):
    horn_length = models.IntegerField()

    class Meta:
        ordering = ["horn_length"]
        verbose_name_plural = "oxen"
```

模型元数据是“任何不是字段的东西”,例如排序选项(`ordering`),数据库表名(`db_table`)或人类可读的单数和复数名称(`verbose_name`和 v`erbose_name_plural`)。不需要,添加到模型是完全可选的。class Meta  
Meta 可以在模型选项参考中找到所有可能选项的完整列表。

### 模型属性

objects  
模型最重要的属性是 `Manager`。它是为 Django 模型提供数据库查询操作的接口,用于 从数据库中检索实例。如果`Manager`未定义自定义,则默认名称为 `objects`。管理员只能通过模型 ​​ 类访问,而不能通过模型 ​​ 实例访问。

### 模型方法

在模型上定义自定义方法,以向对象添加自定义“行级”功能。虽然`Manager`方法旨在执行“表格范围”的事情,但模型方法应该作用于特定的模型实例。  
这是将业务逻辑保存在一个地方的有价值的技术 - 模型  
例如,此模型有一些自定义方法:

```python
from django.db import models

class Person(models.Model):
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)
    birth_date = models.DateField()

    def baby_boomer_status(self):
        "Returns the person's baby-boomer status."
        import datetime
        if self.birth_date < datetime.date(1945, 8, 1):
            return "Pre-boomer"
        elif self.birth_date < datetime.date(1965, 1, 1):
            return "Baby boomer"
        else:
            return "Post-boomer"

    @property
    def full_name(self):
        "Returns the person's full name."
        return '%s %s' % (self.first_name, self.last_name)
```

此示例中的最后一个方法是*属性*。  
该模型实例参考具有的完整列表,自动给每个模型的方法。您可以覆盖其中的大多数 - 请参阅下面的覆盖预定义模型方法 - 但有几个您几乎总是想要定义:  
`__str__()`

> Python“魔术方法”,返回任何对象的字符串表示形式。这是 Python 和 Django 在模型实例需要被强制并显示为纯字符串时将使用的内容。最值得注意的是,当您在交互式控制台或管理员中显示对象时会发生这种情况。  
> 你总是想要定义这个方法; 默认情况下根本没有用。  
> `get_absolute_url()`  
> 这告诉 Django 如何计算对象的 URL。Django 在其管理界面中使用它,并且只要它需要找出对象的 URL。  
> 具有唯一标识它的 URL 的任何对象都应定义此方法。

### 继承模型

模型继承在 Django 中与普通类继承在 Python 中的工作方式几乎完全相同,但也仍有遵循本页开头的内容。这意味着其基类应该继承自 django.db.models.Model。  
您必须做出的唯一决定是您是希望父模型本身是模型(使用自己的数据库表),还是父母只是通过子模型可见的公共信息的持有者。  
Django 中有三种可能的继承方式。  
1.通常,您只想使用父类来保存您不希望为每个子模型键入的信息。这个类不会被孤立使用,所以`抽象基类`就是你所追求的。  
2.如果你是现有模型的子类(可能是完全来自另一个应用程序的东西),并希望每个模型都有自己的数据库表,那么 `多表继承`是最佳选择。  
3.最后,如果您只想修改模型的 Python 级行为,而不以任何方式更改模型字段,则可以使用 `代理模型`。

### 抽象基类

当您想要将一些公共信息放入许多其他模型时,抽象基类非常有用。你写你的基类,并把`abstract=True`在`元` 类。然后,此模型将不用于创建任何数据库表。相反,当它用作其他模型的基类时,其字段将添加到子类的字段中。  
一个例子:

```python
from django.db import models

class CommonInfo(models.Model):
    name = models.CharField(max_length=100)
    age = models.PositiveIntegerField()

    class Meta:
        abstract = True

class Student(CommonInfo):
    home_group = models.CharField(max_length=5)
```

该**Student**模型将有三个领域:`name`,`age`和 `home_group`。该**CommonInfo**模型不能用作普通的 Django 模型,因为它是一个*抽象基类*。它不生成数据库表或具有管理器,并且无法直接实例化或保存。  
从抽象基类继承的字段可以使用其他字段或值覆盖,也可以使用删除 None。  
对于许多用途,这种类型的模型继承将完全符合您的要求。它提供了一种在 Python 级别分解公共信息的方法,同时仍然只在数据库级别为每个子模型创建一个数据库表。

### Meta 继承

当创建抽象基类时,Django 使 您在基类中声明的任何 Meta 内部类可用作属性。如果子类没有声明自己的 Meta 类,它将继承父类的 Meta。如果孩子想要扩展父类的 Meta 类,它可以将其子类化。例如:

```python
from django.db import models

class CommonInfo(models.Model):
    # ...
    class Meta:
        abstract = True
        ordering = ['name']

class Student(CommonInfo):
    # ...
    class Meta(CommonInfo.Meta):
        db_table = 'student_info'
```

Django 确实对抽象基类的 Meta 类进行了一次调整:在安装 Meta 属性之前,它设置了`abstract=False`。这意味着抽象基类的子项本身不会自动成为抽象类。当然,您可以创建一个继承自另一个抽象基类的抽象基类。您只需要记住`abstract=True`每次都明确设置。  
在抽象基类的 Meta 类中包含一些属性是没有意义的。例如,包含`db_table`意味着所有子类(未指定自己的 Meta)将使用相同的数据库表,这几乎肯定不是您想要的。

### 多表继承

Django 支持的第二种模型继承是当层次结构中的每个模型都是模型本身时。每个模型对应于自己的数据库表,可以单独查询和创建。继承关系引入子模型与其每个父模型之间的链接(通过自动创建 OneToOneField)。例如:

```python
from django.db import models

class Place(models.Model):
    name = models.CharField(max_length=50)
    address = models.CharField(max_length=80)

class Restaurant(Place):
    serves_hot_dogs = models.BooleanField(default=False)
    serves_pizza = models.BooleanField(default=False)
```

尽管数据将驻留在不同的数据库表 `Place`中 `Restaurant`,但所有字段都将可用。所以这些都是可能的:

```python
Place.objects.filter(name="Bob's Cafe")
Restaurant.objects.filter(name="Bob's Cafe")
```

如果你的 a `Place` 也是 a `Restaurant`,你可以使用模型名称的小写版本从 **Place**对象到**Restaurant**对象:
![rest](https://upload-images.jianshu.io/upload_images/12747273-8e33e9be8b54ff9b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/838)
但是,如果 p 在上面的示例中不是 a Restaurant(它已直接创建为 Place 对象或是其他类的父级),则引用 p.restaurant 会引发 Restaurant.DoesNotExist 异常。  
自动创建`OneToOneField`的 **Restaurant**,它链接到 Place 看起来像这样:

```python
place_ptr = models.OneToOneField(
    Place, on_delete=models.CASCADE,
    parent_link=True,
)
```

### Meta 和多表继承

在多表继承情况下,子类从其父类的 Meta 类继承是没有意义的。所有的 Meta 选项都已经应用于父类,并且再次应用它们通常只会导致矛盾的行为(这与基类本身不存在的抽象基类情况形成对比)。  
因此,子模型无法访问其父级的 Meta 类。但是,有一些有限的情况,子进程从父进程继承行为:如果子进程没有指定 `ordering`属性或`get_latest_by`属性,它将从其父进程继承它们。  
如果父级有一个排序而你不希望孩子有任何自然顺序,你可以明确地禁用它:

```python
class ChildModel(ParentModel):
    # ...
    class Meta:
        # Remove parent's ordering effect
        ordering = []
```

### 代理模型

使用多表继承时,会为模型的每个子类创建一个新的数据库表。这通常是所需的行为,因为子类需要一个位置来存储基类上不存在的任何其他数据字段。但是,有时您只想更改模型的 Python 行为 - 可能更改默认管理器或添加新方法。  
这就是代理模型继承的用途:为原始模型创建代理。您可以创建,删除和更新代理模型的实例,并且将保存所有数据,就像使用原始(非代理)模型一样。不同之处在于您可以更改代理中的默认模型排序或默认管理器等内容,而无需更改原始内容。  
代理模型声明为普通模型。你通过设置类的 proxy 属性告诉 Django 它是一个代理模型。  
例如,假设您要向 Person 模型添加方法。你可以这样做:

```python
from django.db import models

class Person(models.Model):
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=30)

class MyPerson(Person):
    class Meta:
        proxy = True

    def do_something(self):
        # ...
        pass
```

该 MyPerson 班在同一个数据库表作为它的父工作 Person 类。特别是,任何新的实例 Person 也可以通过 MyPerson,反之亦然:  
![myperson](https://upload-images.jianshu.io/upload_images/12747273-81fc7a330bd5fd6c.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/678)
你仍然可以使用一个代理模型来定义模型的默认排序方法,你也许不会想一直对“Person”进行排序,但是通常情况下用代理模型根据“姓氏”属性进行排序这很简单。:

```python
class OrderedPerson(Person):
    class Meta:
        ordering = ["last_name"]
        proxy = True
```

### 基类限制

一个代理模型必须仅能继承一个非抽象模型类。你不能继承多个非抽象模型类,因为代理模型无法提供不同数据表的任何行间连接。一个代理模型可以继承任意数量的抽象模型类,假如他们没有定义任何的模型字段。一个代理模型也可以继承任意数量的代理模型,只需他们共享同一个非抽象父类

### 模型代理管理器

如果未在代理模型上指定任何模型管理器,它将从其模型父项继承管理器。如果您在代理模型上定义管理器,它将成为默认管理器,尽管在父类上定义的任何管理器仍然可用。  
继续上面的示例,您可以更改查询 Person 模型时使用的默认管理器,如下所示:

```python
from django.db import models

class NewManager(models.Manager):
    # ...
    pass

class MyPerson(Person):
    objects = NewManager()

    class Meta:
        proxy = True
```

如果要在不更换现有默认值的情况下向代理添加新管理器,可以使用自定义管理器文档中描述的技术:创建包含新管理器的基类,并在主基类之后继承:

```python
# Create an abstract class for the new manager.
class ExtraManagers(models.Model):
    secondary = NewManager()

    class Meta:
        abstract = True

class MyPerson(Person, ExtraManagers):
    class Meta:
        proxy = True
```

### 多重继承

正如 Python 的子类化一样,Django 模型可以从多个父模型继承。请记住,正常的 Python 名称解析规则适用。特定名称(例如 Meta)出现的第一个基类将是使用的基类; 例如,这意味着如果多个父类包含一个 Meta 类,则只会使用第一个类,而将忽略所有其他类。  
通常,您不需要从多个父级继承。这有用的主要用例是“混入”类:向每个继承混合的类添加特定的额外字段或方法。尽量使您的继承层次结构尽可能简单明了,这样您就不必费力去找出特定信息来自哪里。  
请注意,从具有公共 id 主键字段的多个模型继承将引发错误。要正确使用多重继承,可以`AutoField`在基本模型中使用`explici`

```python
class Article(models.Model):
    article_id = models.AutoField(primary_key=True)
    ...

class Book(models.Model):
    book_id = models.AutoField(primary_key=True)
    ...

class BookReview(Book, Article):
    pass
```

markdown [Django常用命令]#学习笔记#Web编程#Django

[Django常用命令]#学习笔记#Web编程#Django

Django.md
# [Django 常用命令]#学习笔记 #Web编程 #Django

## **学习笔记**

- [1] 新建项目 django project > `django-admin startproject project_name`
- [2] 新建应用 app > `python manage.py startapp app_name`
- [3] 创建更新数据库表 > 1. 创建更改的文件 > `python manage.py makemigrations` > 2. 将生成的 py 文件应用到数据库 > `python manage.py migrate`
- [4] 使用开发服务器 > `python manage.py runserver 8001`
- [5] 创建管理员用户  
    > `python manage.py createsuperuser`
    > `用户名`  
    > `密码`

markdown [Django前后台的数据传递]#学习笔记#Web编程#Django

[Django前后台的数据传递]#学习笔记#Web编程#Django

Django.md
# [Django 前后台的数据传递]#学习笔记 #Web编程 #Django

## **学习笔记**

Django 从后台往前台传递数据时有多种方法可以实现。

最简单的后台是这样的:

```python
from django.shortcuts import render

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

这个就是返回 index.html 的内容,但是如果要带一些数据一起传给前台的话,该怎么办呢?

### 一 view -> HTML 使用 Django 模版

这里是这样:后台传递一些数据给 html,直接渲染在网页上,不会有什么复杂的数据处理(如果前台要处理数据,那么就传数据给 JS 处理)

Django 代码:

```python
from django.shortcuts import render

def main_page(request):
    data = [1,2,3,4]
    return render(request, 'index.html', {'data': data})
```

html 使用 `{{ }}` 来获取数据

```django
<div>{{ data }}</div>
```

可以对可迭代的数据进行迭代:

```django
{% for item in data%}
<p>{{ item }}</p>
{% endfor %}
```

该方法可以传递各种数据类型,包括`list`,`dict`等等。  
而且除了 `{% for %}` 以外还可以进行`if`判断,大小比较等等。具体的用法读者可以自行搜索。

### 二 view-> JavaScript

如果数据不传给 html 用,要传给 js 用,那么按照上文的方式写会有错误。  
需要注意两点:

> views.py 中返回的函数中的值要用 `json.dumps()` 处理
> 在网页上要加一个 `safe` 过滤器。

代码:  
views.py

```python
# -*- coding: utf-8 -*-

import json
from django.shortcuts import render

def main_page(request):
    list = ['view', 'Json', 'JS']
    return render(request, 'index.html', {
            'List': json.dumps(list),
        })
```

JavaScript 部分:

```django
var List = {{ List|safe }};
```

### 三 JavaScript Ajax 动态刷新页面

这个标题的意思是:网页前台使用 Ajax 发送请求,后台处理数据后返回数据给前台,前台不刷新网页动态加载数据

Django 代码:

```python
def scene_update_view(request):
    if request.method == "GET":
            name = request.GET.get('name')
            status = 0
            result = "Error!"
            return HttpResponse(json.dumps({
                "status": status,
                "result": result
            }))
```

JS 代码:

```js
function getSceneId(scece_name, td) {
  var post_data = {
    name: scece_name
  };

  $.ajax({
    url: "TEST/", //url路径
    type: "GET",
    data: post_data,
    success: function(data) {
      data = JSON.parse(data);
      if (data["status"] == 1) {
        setSceneTd(data["result"], scece_name, td);
      } else {
        alert(data["result"]);
      }
    }
  });
}
```

JS 发送 ajax 请求,后台处理请求并返回 status, result  
在 success: 后面定义回调函数处理返回的数据,需要使用 `JSON.parse(data)`  
可以将数据直接放在 url 里面

```js
(2)可以将数据直接放到URL里

<script language="JavaScript">
    function Ssss(id) {
        $.ajax({
            type: "GET",
            url: "test/?domain_name="+id,    //后台处理函数的url和数据
            success: function (result) {  //获取后台处理后传过来的result
                alert(result)
            },
        });
    }
</script>
```

markdown [Django与Ajax实现网页动态数据显示]#学习笔记#Web编程#Django

[Django与Ajax实现网页动态数据显示]#学习笔记#Web编程#Django

DjangoAjax.md
# [Django 与 Ajax 实现网页动态数据显示]#学习笔记 #Web编程 #Django

## **学习笔记**

- [1] 创建后台读取数据函数,用于后台从数据库读取数据。在 views.py 文件内增加以下代码

  > ```python
  > from django.http import JsonResponse
  >
  > def data_fresh(request):
  >     context = {"data1": Test.objects.order_by("-time")[0].temp1,
  >                "data2": Test.objects.order_by("-time")[0].temp2}
  >     return JsonResponse(context)
  > ```
  >
  > **data_fresh**是函数名  
  > **Test**是 Django 项目下的模型  
  > **order_by(“-time”)[0]** 指按时间列倒序排列并取第一行数据  
  > **temp1**是第一行数据里的 temp1 数据  
  > 如果没有数据库数据的话,直接写成固定的数据用来测试也是可以的

- [2] 加载函数,让 HTML 页面能够访问到函数。在 urls.py 添加一下代码

```python
urlpatterns = [
    path('data_fresh/', views.data_fresh, name="data_fresh"),
]
```

- [3] 前端使用 jQuery 访问后台函数,要实现数据动态显示,还需要增加定时程序,在 HTML 页面插入以下代码

```js
<script>
    $(document).ready(function(){
        function refresh(){
            $.getJSON("/data_fresh/", function (ret) {
                $('#result').html(ret.data1);
                $('#result2').html(ret.data2);
            })
        }
        setInterval(refresh, 3000)
    })
</script>
```

markdown [Ubuntu系统常见故障]#学习笔记#嵌入式系统#Ubuntu

[Ubuntu系统常见故障]#学习笔记#嵌入式系统#Ubuntu

Ubuntu.md
# [Ubuntu 系统常见故障]#学习笔记 #嵌入式系统 #Ubuntu

## **学习笔记**

### ibus 无法按数字键取词

`rm -rf ~/.cache/ibus/libpinyin`  
有个人习惯词先备份 user_bigram.db  
重启 `ibus restart`

### 安装软件 has install-snap change in progress 错误

其实就是软件之前安装了一次,只是没安装完。

先`snap changes`  
可以看到 ID=5 是我之前安装失败的。  
现在我们终止它  
`sudo snap abort 5`  
好了,可以重新安装了

markdown [Ubuntu系统常用指令]#学习笔记#嵌入式系统#Ubuntu

[Ubuntu系统常用指令]#学习笔记#嵌入式系统#Ubuntu

Ubuntu.md
# [Ubuntu 系统常用指令]#学习笔记 #嵌入式系统 #Ubuntu

## **学习笔记**

### 卸载软件

- 1.获取已安装应用列表,并找到需要卸载的应用
  > `dpkg --list`
- 2.卸载程序  
  a) 移除程序与配置文件

  > `sudo apt-get --purge remove <programname>`

  b) 仅移除程序保留配置文件

  > `sudo apt-get remove <programname>`

### 查看应用的安装路径

- 方法 1:`whereis python`  
  查看所有 python 的路径,不止一个
- 方法 2:`which python`  
  查看当前使用的 python 路径

### dd 硬盘拷贝

- 1.备份 >`sudo dd if=/dev/sda of=/media/disk1/sda-image.img bs=4M`
- 2.恢复 >`sudo dd if=/media/disk1/sda-image.img of=/dev/sda bs=4M`

### 改变文件或目录的所有者

- 1.[语法] `sudo chown -R 用户名 文件或目录`-R 代表该目录中的所有文件或目录全部改变
- 2.[示例] `sudo chown -R dongliang library/`

### 改变文件或目录权限

- `sudo chmod 666 library/Memory_EEPROM.lib`

markdown CLI提示。节点工具

usfull命令的集合

http-server.md
diable catch   

`$ npm run build && http-server -c-1` minus 1

markdown MySQL备忘单

MySQL备忘单

mysql_cheat_sheet.md
# MySQL Cheat Sheet

> Help with SQL commands to interact with a MySQL database

## MySQL Locations
* Mac             */usr/local/mysql/bin*
* Windows         */Program Files/MySQL/MySQL _version_/bin*
* Xampp           */xampp/mysql/bin*

## Add mysql to your PATH

```bash
# Current Session
export PATH=${PATH}:/usr/local/mysql/bin
# Permanantly
echo 'export PATH="/usr/local/mysql/bin:$PATH"' >> ~/.bash_profile
```

On Windows - https://www.qualitestgroup.com/resources/knowledge-center/how-to-guide/add-mysql-path-windows/

## Login

```bash
mysql -u root -p
```

## Show Users

```sql
SELECT User, Host FROM mysql.user;
```

## Create User

```sql
CREATE USER 'someuser'@'localhost' IDENTIFIED BY 'somepassword';
```

## Grant All Priveleges On All Databases

```sql
GRANT ALL PRIVILEGES ON * . * TO 'someuser'@'localhost';
FLUSH PRIVILEGES;
```

## Show Grants

```sql
SHOW GRANTS FOR 'someuser'@'localhost';
```

## Remove Grants

```sql
REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'someuser'@'localhost';
```

## Delete User

```sql
DROP USER 'someuser'@'localhost';
```

## Exit

```sql
exit;
```

## Show Databases

```sql
SHOW DATABASES
```

## Create Database

```sql
CREATE DATABASE acme;
```

## Delete Database

```sql
DROP DATABASE acme;
```

## Select Database

```sql
USE acme;
```

## Create Table

```sql
CREATE TABLE users(
id INT AUTO_INCREMENT,
   first_name VARCHAR(100),
   last_name VARCHAR(100),
   email VARCHAR(50),
   password VARCHAR(20),
   location VARCHAR(100),
   dept VARCHAR(100),
   is_admin TINYINT(1),
   register_date DATETIME,
   PRIMARY KEY(id)
);
```

## Delete / Drop Table

```sql
DROP TABLE tablename;
```

## Show Tables

```sql
SHOW TABLES;
```

## Insert Row / Record

```sql
INSERT INTO users (first_name, last_name, email, password, location, dept, is_admin, register_date) values ('Brad', 'Traversy', 'brad@gmail.com', '123456','Massachusetts', 'development', 1, now());
```

## Insert Multiple Rows

```sql
INSERT INTO users (first_name, last_name, email, password, location, dept,  is_admin, register_date) values ('Fred', 'Smith', 'fred@gmail.com', '123456', 'New York', 'design', 0, now()), ('Sara', 'Watson', 'sara@gmail.com', '123456', 'New York', 'design', 0, now()),('Will', 'Jackson', 'will@yahoo.com', '123456', 'Rhode Island', 'development', 1, now()),('Paula', 'Johnson', 'paula@yahoo.com', '123456', 'Massachusetts', 'sales', 0, now()),('Tom', 'Spears', 'tom@yahoo.com', '123456', 'Massachusetts', 'sales', 0, now());
```

## Select

```sql
SELECT * FROM users;
SELECT first_name, last_name FROM users;
```

## Where Clause

```sql
SELECT * FROM users WHERE location='Massachusetts';
SELECT * FROM users WHERE location='Massachusetts' AND dept='sales';
SELECT * FROM users WHERE is_admin = 1;
SELECT * FROM users WHERE is_admin > 0;
```

## Delete Row

```sql
DELETE FROM users WHERE id = 6;
```

## Update Row

```sql
UPDATE users SET email = 'freddy@gmail.com' WHERE id = 2;

```

## Add New Column

```sql
ALTER TABLE users ADD age VARCHAR(3);
```

## Modify Column

```sql
ALTER TABLE users MODIFY COLUMN age INT(3);
```

## Order By (Sort)

```sql
SELECT * FROM users ORDER BY last_name ASC;
SELECT * FROM users ORDER BY last_name DESC;
```

## Concatenate Columns

```sql
SELECT CONCAT(first_name, ' ', last_name) AS 'Name', dept FROM users;

```

## Select Distinct Rows

```sql
SELECT DISTINCT location FROM users;

```

## Between (Select Range)

```sql
SELECT * FROM users WHERE age BETWEEN 20 AND 25;
```

## Like (Searching)

```sql
SELECT * FROM users WHERE dept LIKE 'd%';
SELECT * FROM users WHERE dept LIKE 'dev%';
SELECT * FROM users WHERE dept LIKE '%t';
SELECT * FROM users WHERE dept LIKE '%e%';
```

## Not Like

```sql
SELECT * FROM users WHERE dept NOT LIKE 'd%';
```

## IN

```sql
SELECT * FROM users WHERE dept IN ('design', 'sales');
```

## Create & Remove Index

```sql
CREATE INDEX LIndex On users(location);
DROP INDEX LIndex ON users;
```

## New Table With Foreign Key (Posts)

```sql
CREATE TABLE posts(
id INT AUTO_INCREMENT,
   user_id INT,
   title VARCHAR(100),
   body TEXT,
   publish_date DATETIME DEFAULT CURRENT_TIMESTAMP,
   PRIMARY KEY(id),
   FOREIGN KEY (user_id) REFERENCES users(id)
);
```

## Add Data to Posts Table

```sql
INSERT INTO posts(user_id, title, body) VALUES (1, 'Post One', 'This is post one'),(3, 'Post Two', 'This is post two'),(1, 'Post Three', 'This is post three'),(2, 'Post Four', 'This is post four'),(5, 'Post Five', 'This is post five'),(4, 'Post Six', 'This is post six'),(2, 'Post Seven', 'This is post seven'),(1, 'Post Eight', 'This is post eight'),(3, 'Post Nine', 'This is post none'),(4, 'Post Ten', 'This is post ten');
```

## INNER JOIN

```sql
SELECT
  users.first_name,
  users.last_name,
  posts.title,
  posts.publish_date
FROM users
INNER JOIN posts
ON users.id = posts.user_id
ORDER BY posts.title;
```

## New Table With 2 Foriegn Keys

```sql
CREATE TABLE comments(
	id INT AUTO_INCREMENT,
    post_id INT,
    user_id INT,
    body TEXT,
    publish_date DATETIME DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY(id),
    FOREIGN KEY(user_id) references users(id),
    FOREIGN KEY(post_id) references posts(id)
);
```

## Add Data to Comments Table

```sql
INSERT INTO comments(post_id, user_id, body) VALUES (1, 3, 'This is comment one'),(2, 1, 'This is comment two'),(5, 3, 'This is comment three'),(2, 4, 'This is comment four'),(1, 2, 'This is comment five'),(3, 1, 'This is comment six'),(3, 2, 'This is comment six'),(5, 4, 'This is comment seven'),(2, 3, 'This is comment seven');
```

## Left Join

```sql
SELECT
comments.body,
posts.title
FROM comments
LEFT JOIN posts ON posts.id = comments.post_id
ORDER BY posts.title;

```

## Join Multiple Tables

```sql
SELECT
comments.body,
posts.title,
users.first_name,
users.last_name
FROM comments
INNER JOIN posts on posts.id = comments.post_id
INNER JOIN users on users.id = comments.user_id
ORDER BY posts.title;

```

## Aggregate Functions

```sql
SELECT COUNT(id) FROM users;
SELECT MAX(age) FROM users;
SELECT MIN(age) FROM users;
SELECT SUM(age) FROM users;
SELECT UCASE(first_name), LCASE(last_name) FROM users;

```

## Group By

```sql
SELECT age, COUNT(age) FROM users GROUP BY age;
SELECT age, COUNT(age) FROM users WHERE age > 20 GROUP BY age;
SELECT age, COUNT(age) FROM users GROUP BY age HAVING count(age) >=2;

```