# 1000、Django错误



### 错误： no such table: auth\_user

```bash
python manage.py migrate
python manage.py createsuperuser
```

***

\##　错误： return database\_name == ':memory:' or 'mode=memory' in database\_name

```bash
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': str(BASE_DIR / 'db.sqlite3'),
    }
}
```

***

Django3+celery4.4报错DatabaseWrapper objects created in a thread can only be used in that same thread.

**执行异步任务时报错：**

django.db.utils.DatabaseError: DatabaseWrapper objects created in a thread can only be used in that same thread. The object with alias 'default' was created in thread id 2068603070080 and this is thread id 2069065236128.

解决方法：

原先启动命令：

```python
windows: celery -A xxx worker -l info -P eventlet        可能需安装 eventlet
Linux: celery -A xxx worker -l info
```

替换为：

```python
windows: celery -A xxx  worker -l info  -P eventlet --pool=solo
Linux: celery -A xxx  worker -l info  --pool=solo
```

### 解决django同步数据库的时候app models表没有成功创建的问题

问题描述：

* 在django中创建了一个app，而且在app中自定义创建了几个数据表，在同步的时候系统自带的表可以成功， 但是 models 中的没有生效，而且进入对应 app下的migrations目录，发现为空，应该如何解决呢！

解决方式：

```python
python3 manage.py makemigrations --empty app_name  # app_name 就是你的app名字，此处要写成自己的app名字
python3 manage.py makemigrations   # 再次正常运行生成迁移文件的命令
python3 manage.py migrate          # 同步数据库
```

然后就会看到成功了！

### SQLite 版本库错误

```bash
  File "/home/celery/venv/lib/python3.6/site-packages/django/db/backends/sqlite3/base.py", line 65, in check_sqlite_version
    raise ImproperlyConfigured('SQLite 3.8.3 or later is required (found %s).' % Database.sqlite_version)
django.core.exceptions.ImproperlyConfigured: SQLite 3.8.3 or later is required (found 3.7.17).
```

两个解决办法 方法一：给Django降级

```bash
pip install django==2.1.7
```

方法二：升级SQLite

> 下载地址：https://www.sqlite.org/download.html

```bash
# 链接最好重新获取，否则可能不是最新版本
wget https://www.sqlite.org/2019/sqlite-autoconf-3300100.tar.gz
tar zxvf sqlite-autoconf-3300100.tar.gz
cd sqlite-autoconf-3300100/
./configure
make & make install

# 查看新旧版本
/usr/local/bin/sqlite3 --version
/usr/bin/sqlite3 --version

# 更换
mv /usr/bin/sqlite3  /usr/bin/sqlite3_old
ln -s /usr/local/bin/sqlite3 /usr/bin/sqlite3

# 当前环境变量库
export LD_LIBRARY_PATH="/usr/local/lib"
```

检查Python的SQLite3版本

```python
(application) [root@localhost application]# python
Python 3.6.5 (default, Jul  9 2019, 20:03:55) 
[GCC 4.8.5 20150623 (Red Hat 4.8.5-36)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import sqlite3
>>> sqlite3.sqlite_version
'3.30.1'
>>> exit()  
```

### Django3+celery4.4报错DatabaseWrapper objects created in a thread can only be used in that same thread.

执行异步任务时报错：

django.db.utils.DatabaseError: DatabaseWrapper objects created in a thread can only be used in that same thread. The object with alias 'default' was created in thread id 2068603070080 and this is thread id 2069065236128.

解决方法：

原先启动命令：

```python
windows: celery -A xxx worker -l info -P eventlet        可能需安装 eventlet
Linux: celery -A xxx worker -l info
```

替换为：

```python
windows: celery -A xxx  worker -l info  -P eventlet --pool=solo
Linux: celery -A xxx  worker -l info  --pool=solo
```

### django后台自定义字段展示，失去排序，添加admin\_order\_field即可

例如： `model.py`

```python
suceess_html = '<span style="padding:2px;background-color:green;color:white;border-radius: 30%;">{}</span>'
warnign_html = '<span style="padding:2px;background-color:yellow;color:black;border-radius: 30%;">{}</span>'
error_html = '<span style="padding:2px;background-color:red;color:white;border-radius: 30%;">{}</span>'

class Dm_AccountModel(models.Model):
    '''域名解析商'''
    ns_st = models.CharField(max_length=50, choices=(('使用中', '使用中'), ('备用', '备用'), ('弃用', '弃用')), verbose_name='域商状态')
    createor = models.ForeignKey( User, verbose_name='创建人', null=True, on_delete=models.SET_NULL)
    last_editor = models.CharField(max_length=50, null=True, verbose_name='最后编辑者')

    def color(self):
        if self.ns_st == '使用中':
            html = suceess_html
        elif self.ns_st == '备用':
            html = warnign_html
        else:
            html = error_html
        return format_html(html, self.ns_st)
    color.short_description = "域商状态"
    color.admin_order_field = 'ns_st'       # 添加 admin_order_field 实现 admin 后台排序
    ns_st_color = color
```

`admin.py`

```python
class Dm_AccountModelAdmin(admin.ModelAdmin):
    list_display = ('ns_st_color',)

    # 提交时候自动设置当前用户为创建人
    def save_model(self, request, obj, form, change):
        obj.last_editor = request.user.username     # 设置最后编辑的人为当前登录用户
        if not obj.createor:     # 假如没有创建者，就设置当前用户为创建者
            obj.createor = request.user
        obj.save()
```

### CELERY 4.3.0 任务失败重试机制

#### 存在的现象

在异步调用任务中经常需要调用第三方的api请求，如果一次执行失败，则应该进行重试执行。否则，如果在执行一些连续性的chain链条任务，前面执行失败，那么后续的也就不用执行了。

下面来看看一个发送邮件失败，然后重试执行的示例。

#### CELERY任务的文档结构

#### 错误重试示例

#### 故意将邮件服务的地址配置错误

为了做到错误的演示，我首先将发送邮件的smtp地址写错，如下：

那么稍后执行发送邮件的时候，就一定会报找不到smtp的错误。

#### 编写错误重试的TASK任务

```python
# 定义任务函数
@celery_app.task(bind=True)
def send_register_active_email(self,to_email, username, token):
    '''发送**邮件'''
    # 组织邮件信息
    subject = '欢迎信息'
    message = ''
    sender = settings.EMAIL_FROM
    receiver = [to_email]
    html_message = '<h1>%s, 欢迎您成为xxx注册会员</h1>请点击下面链接**您的账户<br/><a href="http://127.0.0.1:8000/user/active/%s">http://127.0.0.1:8000/user/active/%s</a>' % (username, token, token)

    print("=========== 执行发送邮件 ===============")

    try:
        send_mail(subject, message, sender, receiver, html_message=html_message)
    except Exception as e:
        """
                邮件发送失败，使用retry进行重试

                retry的参数可以有：
                    exc：指定抛出的异常
                    throw：重试时是否通知worker是重试任务
                    eta：指定重试的时间／日期
                    countdown：在多久之后重试（每多少秒重试一次）
                    max_retries：最大重试次数
                """
        raise self.retry(exc=e, countdown=3, max_retries=5)
```

该示例任务将会进行调用发送邮件，当发生错误后，间隔3秒则重试执行一次，总共5次。 可以通过`print`的打印信息来确认重试的次数。

#### 启动CELERY任务

windows启动命令：

```
celery -A celery_tasks worker -l info --pool=solo -P eventlet
```

linux启动命令：

```
celery -A celery_tasks worker -l info
```

#### 执行CELERY任务

启动完毕celery之后，那么下面进行交互模式进行测试，执行如下：

```
In [1]: from celery_tasks.tasks import send_register_active_email

In [2]: to_email = 'lijw@******.cn'

In [3]: token = '123456'

In [4]: username = 'lijw'

In [5]: send_register_active_email.delay(to_email,username,token)
Out[5]: <AsyncResult: 02deebc0-5d64-43f9-9ad5-5ccfe260ec70>
12345678910
```

执行完毕任务后，查看celery的执行日志，如下：

```
[2019-10-21 14:01:09,508: INFO/MainProcess] celery@junwei1 ready.
[2019-10-21 14:01:09,509: INFO/MainProcess] pidbox: Connected to redis://127.0.0.1:6379/8.
[2019-10-21 14:01:14,353: INFO/MainProcess] Received task: celery_tasks.tasks.send_register_active_email[7b921776-f6a6-4da0-9c71-b04aac0d139a]

# 任务第一次执行，然后执行失败
[2019-10-21 14:01:14,354: WARNING/MainProcess] =========== 执行发送邮件 ===============
[2019-10-21 14:01:15,311: INFO/MainProcess] Received task: celery_tasks.tasks.send_register_active_email[7b921776-f6a6-4da0-9c71-b04aac0d139a]  ETA:[2019-10-21 06:01:18.21
8857+00:00]
[2019-10-21 14:01:15,345: INFO/MainProcess] Task celery_tasks.tasks.send_register_active_email[7b921776-f6a6-4da0-9c71-b04aac0d139a] retry: Retry in 3s: gaierror(11001, 'N
o address found')

# 当执行错误之后，下面则会重试执行5次任务，直到成功，或者失败
[2019-10-21 14:01:18,224: WARNING/MainProcess] =========== 执行发送邮件 ===============
[2019-10-21 14:01:18,253: INFO/MainProcess] Received task: celery_tasks.tasks.send_register_active_email[7b921776-f6a6-4da0-9c71-b04aac0d139a]  ETA:[2019-10-21 06:01:21.22
5853+00:00]
[2019-10-21 14:01:18,265: INFO/MainProcess] Task celery_tasks.tasks.send_register_active_email[7b921776-f6a6-4da0-9c71-b04aac0d139a] retry: Retry in 3s: gaierror(11001, 'N
o address found')
[2019-10-21 14:01:21,227: WARNING/MainProcess] =========== 执行发送邮件 ===============
[2019-10-21 14:01:21,255: INFO/MainProcess] Received task: celery_tasks.tasks.send_register_active_email[7b921776-f6a6-4da0-9c71-b04aac0d139a]  ETA:[2019-10-21 06:01:24.22
8790+00:00]
[2019-10-21 14:01:21,264: INFO/MainProcess] Task celery_tasks.tasks.send_register_active_email[7b921776-f6a6-4da0-9c71-b04aac0d139a] retry: Retry in 3s: gaierror(11001, 'N
o address found')
[2019-10-21 14:01:24,243: WARNING/MainProcess] =========== 执行发送邮件 ===============
[2019-10-21 14:01:24,280: INFO/MainProcess] Received task: celery_tasks.tasks.send_register_active_email[7b921776-f6a6-4da0-9c71-b04aac0d139a]  ETA:[2019-10-21 06:01:27.24
4729+00:00]
[2019-10-21 14:01:24,291: INFO/MainProcess] Task celery_tasks.tasks.send_register_active_email[7b921776-f6a6-4da0-9c71-b04aac0d139a] retry: Retry in 3s: gaierror(11001, 'N
o address found')
[2019-10-21 14:01:27,245: WARNING/MainProcess] =========== 执行发送邮件 ===============
[2019-10-21 14:01:27,271: INFO/MainProcess] Received task: celery_tasks.tasks.send_register_active_email[7b921776-f6a6-4da0-9c71-b04aac0d139a]  ETA:[2019-10-21 06:01:30.24
6720+00:00]
[2019-10-21 14:01:27,281: INFO/MainProcess] Task celery_tasks.tasks.send_register_active_email[7b921776-f6a6-4da0-9c71-b04aac0d139a] retry: Retry in 3s: gaierror(11001, 'N
o address found')
[2019-10-21 14:01:30,261: WARNING/MainProcess] =========== 执行发送邮件 ===============
[2019-10-21 14:01:30,279: ERROR/MainProcess] Task celery_tasks.tasks.send_register_active_email[7b921776-f6a6-4da0-9c71-b04aac0d139a] raised unexpected: gaierror(11001, 'N
o address found')
Traceback (most recent call last):
  ....
    raise socket.gaierror(socket.EAI_NONAME, 'No address found')
socket.gaierror: [Errno 11001] No address found
123456789101112131415161718192021222324252627282930313233343536373839
```

可以看到，上面的日志中的打印信息。 第一次执行任务，则发送了一次报错。 随后一直重试执行了5次都报错，说明重试的5次是从第一次执行失败后计算的。

### Django 渲染模板与 vue 的 \{{ \}} 冲突解决方法

如果不可避免的在同一个页面里既有 django 渲染又有 vue 渲染的部分，可有 2 种方式解决

#### 方法一：

　　采用 vue 的 [delimiters](https://cn.vuejs.org/v2/api/#delimiters) 分隔符。

```
new Vue({
  delimiters: ["{[", "]}"] // 可自定义符号
})
```

**方法二：**

建议把 vue 的部分用

包起来。

见文档：https://docs.djangoproject.com/en/2.2/ref/templates/builtins/#verbatim

```
<div data-gb-custom-block data-tag="verbatim">


        <div>{{ text }}</div>

</div>
```
