79

当我从django-admin用户密码创建用户时,密码被加密。但是当我从 django shell 创建用户时,用户密码以纯文本形式保存。例子 :

{
    "date_joined": "2013-08-28T04:22:56.322185",
    "email": "",
    "first_name": "",
    "id": 5,
    "is_active": true,
    "is_staff": false,
    "is_superuser": false,
    "last_login": "2013-08-28T04:22:56.322134",
    "last_name": "",
    "password": "pbkdf2_sha256$10000$iGKbck9CED0b$6hWrKYiMPNGKhcfPVGal2YP4LkuP3Qwem+2ydswWACk=",
    "resource_uri": "/api/v1/user/5/",
    "username": "user4"
},
{
    "date_joined": "2013-08-29T01:15:36.414887",
    "email": "test@ophio",
    "first_name": "",
    "id": 6,
    "is_active": true,
    "is_staff": true,
    "is_superuser": true,
    "last_login": "2013-08-29T01:15:36.414807",
    "last_name": "",
    "password": "123test",
    "resource_uri": "/api/v1/user/6/",
    "username": "test3"
} 

我正在尝试为一个简单的博客应用程序制作 REST 样式的 api:当我尝试通过发布请求 [通过传递 JSON] 插入用户时,密码被保存为纯文本。如何覆盖此行为。

4

7 回答 7

171

您不应该User(...)像其他人建议的那样通过正常语法创建用户。您应该始终使用User.objects.create_user(),它负责正确设置密码。

user@host> manage.py shell
>>> from django.contrib.auth.models import User
>>> user=User.objects.create_user('foo', password='bar')
>>> user.is_superuser=True
>>> user.is_staff=True
>>> user.save()
于 2013-08-29T07:34:38.597 回答
19

为 django 创建超级用户的最快方法,在 shell 中输入:

python manage.py createsuperuser
于 2017-08-19T19:41:55.140 回答
17

要使脚本自动化,您可以使用管道功能来执行命令列表,而无需每次都输入。

### content of "create_user.py" file
from django.contrib.auth import get_user_model

# see ref. below
UserModel = get_user_model()

if not UserModel.objects.filter(username='foo').exists():
    user=UserModel.objects.create_user('foo', password='bar')
    user.is_superuser=True
    user.is_staff=True
    user.save()

参考:get_user_model()

请记住先激活 VirtualEnv,然后运行以下命令(适用于 Linux):

cat create_user.py | python manage.py shell

如果您使用 window 则将cat命令替换为type命令

type create_user.py | python manage.py shell

或适用于 Linux 和 Windows

# if the script is not in the same path as manage.py, then you must 
#    specify the absolute path of the "create_user.py" 
python manage.py shell < create_user.py

陷阱:不要在任何缩进块中包含空行,当您将代码粘贴到 REPL 中时,请考虑一下。如果您有任何空行,它将无法正常工作。

于 2017-11-10T16:53:34.673 回答
3

您用于user.set_password在 django shell 中设置密码。我什至不确定通过直接设置密码user.password是否可行,因为 Django 需要密码的哈希值。

password字段不存储密码;它将它们存储为<algorithm>$<iterations>$<salt>$<hash>,因此当它检查密码时,它会计算哈希值并进行比较。我怀疑用户实际上有一个密码,其计算的密码哈希是<algorithm>$<iterations>$<salt>$<hash>形式的。

如果您获得了json创建用户所需的所有信息,您可以这样做

User.objects.create_user(**data)

假设您传递的 json 称为数据。

注意:如果您在data.

如果你真的想覆盖这个行为,你可以这样做

def override_setattr(self,name,value):
    if name == 'password':
        self.set_password(value)
    else:
        super().__setattr__(self,name,value) #or however super should be used for your version

User.__setattr__ = override_setattr

我没有测试过这个解决方案,但它应该可以工作。使用风险自负。

于 2013-08-29T06:40:35.830 回答
3

要创建用户,请执行:

$ python manage.py shell
>>>> from django.contrib.auth.models import User
>>>> user = User.objects.create_user('USERNAME', 'MAIL_NO_REQUIRED', 'PASSWORD')
于 2018-03-02T10:46:51.230 回答
3

回答那些使用 django 1.9 或更高版本的人,因为from django.contrib.auth.models import User已弃用(可能更早),但绝对是 1.9。

而是这样做:在bash中:

python manage.py shell

在 python shell 中创建一个带密码的用户:

from django.apps import apps
User = apps.get_model('user', 'User')
me = User.objects.create(first_name='john', email='johnsemail@email.com') # other_info='other_info', etc.
me.set_password('WhateverIwant')  # this will be saved hashed and encrypted
me.save()

如果来自 API,您可能应该这样应用表单:

import json
User = get_model('User')
class UserEditForm(BaseModelForm):
        """This allows for validity checking..."""

        class Meta:
            model = User
            fields = [
                'first_name', 'password', 'last_name',
                'dob', # etc...
            ]
# collect the data from the API:
post_data = request.POST.dict()
data = {
'first_name': post_data['firstName'],
'last_name': post_data['firstName'],
'password': post_data['password'], etc.
}
dudette = User()  # (this is for create if its edit you can get the User by pk with User.objects.get(pk=kwargs.pk))
form = UserEditForm(data, request.FILES, instance=dudette)
if form.is_valid():
    dudette = form.save()
else:
    dudette = {'success': False, 'message': unicode(form.errors)}
return json.dumps(dudette.json())  # assumes you have a json serializer on the model called def json(self):
于 2016-11-01T20:06:30.897 回答
-5

有几种方法可以从 django-shell 为 django 用户对象设置密码。

user = User(username="django", password = "secret")
user.save()

这将存储加密的密码。

user = User(username="django")
user.set_password("secret")
user.save()

这将存储加密的密码。

但,

user = User(username="django")
user.password="secret"
user.save()

这将存储纯文本密码。由于您直接修改属性,因此没有应用散列/加密。

于 2013-08-29T07:00:07.303 回答