# 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>
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://close.gitbook.io/yun-wei-bi-ji/python/django/1000django-cuo-wu.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
