如何使用迁移框架添加 Django REST 框架身份验证令牌

Posted

技术标签:

【中文标题】如何使用迁移框架添加 Django REST 框架身份验证令牌【英文标题】:How do you use the migration framework to add Django REST Framework Authentication Tokens 【发布时间】:2015-12-19 19:52:53 【问题描述】:

我正在使用 Django REST 框架设置一个新的 API,我需要向所有现有用户添加 Auth 令牌。文档说要做:

from django.contrib.auth.models import User
from rest_framework.authtoken.models import Token

for user in User.objects.all():
    Token.objects.get_or_create(user=user)

但理想情况下,这应该使用 Django 的新迁移框架来实现。

有没有简单的方法可以做到这一点?

【问题讨论】:

【参考方案1】:

这里的诀窍是知道Token 使用自定义save() 方法来生成唯一的token.key,但自定义save() 方法不在迁移中运行。因此,第一个令牌将有一个空白键,而第二个令牌将失败并显示 IntegrityError,因为它们的键也是空白且不唯一。

相反,将generate_key() 代码复制到您的迁移中,如下所示:

# Generated with `manage.py makemigrations --empty YOUR-APP`.

import binascii
import os

from django.db import migrations

# Copied from rest_framework/authtoken/models.py.
def generate_key():
    return binascii.hexlify(os.urandom(20)).decode()

def create_tokens(apps, schema_editor):
    User = apps.get_model('auth', 'User')
    Token = apps.get_model('authtoken', 'Token')
    for user in User.objects.filter(auth_token__isnull=True):
        token, _ = Token.objects.get_or_create(user=user, key=generate_key())

class Migration(migrations.Migration):

    dependencies = [
        ('YOUR-APP', 'YOUR-PREVIOUS-MIGRATION'),
    ]

    operations = [
        migrations.RunPython(create_tokens),
    ]

您应该避免将 rest_framework 代码直接导入迁移中,否则有一天您的迁移将无法运行,因为您决定删除 rest_framework 或更改库的界面。迁移需要及时冻结。

【讨论】:

【参考方案2】:

首先为您希望使用它的应用创建一个空迁移。就我而言,我有一个名为 users 的应用程序,这种东西就在其中,所以我跑了:

manage.py makemigrations users --empty

这在我的迁移目录中创建了一个新文件,我可以使用以下内容对其进行更新:

# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models, migrations
from rest_framework.authtoken.models import Token
from django.contrib.auth.models import User

def add_tokens(apps, schema_editor):
    print "Adding auth tokens for the API..."
    for user in User.objects.all():
        Token.objects.get_or_create(user=user)

def remove_tokens(apps, schema_editor):
    print "Deleting all auth tokens for the API..."
    Token.objects.all().delete()

class Migration(migrations.Migration):

    dependencies = [
        ('users', '0002_load_initial_data'),
    ]

    operations = [
        migrations.RunPython(add_tokens, reverse_code=remove_tokens),
    ]

【讨论】:

您不应将代码导入迁移中,否则在您决定删除rest_frameworkrest_framework 接口更改后的某一天,您的迁移将开始失败。迁移需要完全独立。

以上是关于如何使用迁移框架添加 Django REST 框架身份验证令牌的主要内容,如果未能解决你的问题,请参考以下文章

如何在 django rest 框架中添加自定义权限和角色

如何在 django rest 框架中仅使用特定变体对象将项目添加到愿望清单?

你如何在 django rest 框架中实现 CSRF 令牌?

如何在Django rest框架中一键将学生添加到老师的课堂

我们如何使用基于函数的视图在 django rest 框架中发布数据?

如何在 django REST 框架中修改 request.data