如何从 django shell 创建用户
Posted
技术标签:
【中文标题】如何从 django shell 创建用户【英文标题】:How to create user from django shell 【发布时间】:2013-09-01 11:07:15 【问题描述】:当我从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] 插入用户时,密码将保存为纯文本。 如何覆盖此行为。
【问题讨论】:
你是如何将 json 放入数据库的? 我正在使用 django-tastypie 。 这能回答你的问题吗? How to create a user in Django? 【参考方案1】:您不应该像其他人建议的那样通过普通的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()
【讨论】:
我看不出您的“完整问题”与我的回答有何冲突。如果你需要在代码中创建用户,你应该使用User.objects.create_user()
。
这个神奇的 User 对象从何而来? H8 给出的代码示例没有关键的“导入”位。 django.contrib.auth.models
create_user()
的文档:docs.djangoproject.com/en/1.8/topics/auth/customizing/…
这可以简化为from django.contrib.auth.models import User; User.objects.create_superuser('foo', password='bar')
。
如果你定义了自己的用户,你需要先from django.contrib.auth import get_user_model
然后User = get_user_model()
【参考方案2】:
django创建超级用户最快的方法,输入shell:
python manage.py createsuperuser
【讨论】:
有没有办法以非交互方式做到这一点? 这其实比敲代码慢很多!! @ChandanPurohit 你不应该在代码中使用它,你可以使用这个命令从终端创建用户。【参考方案3】:要使脚本自动化,您可以使用管道功能来执行命令列表,而无需每次都输入。
### 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
如果您使用窗口,则将 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 中时可以这样想。如果您有任何空行,它将无法正常工作。
【讨论】:
【参考方案4】:您使用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
我没有测试过这个解决方案,但它应该可以工作。使用风险自负。
【讨论】:
也许我需要覆盖用户这样做的默认保存。 我认为你不应该这样做,因为它是默认的 User 对象(这意味着如果你这样做了,除非你子类化,否则它会搞砸使用 User 的其他人)。使用set_password
有什么问题?
sry ,但我对原始问题进行了一些更改,以使其与我正在做的事情更加相关。【参考方案5】:
回答那些使用 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):
【讨论】:
请注意官方文档(docs.djangoproject.com/en/1.10/topics/auth/default/…)从django.contrib.auth.models
导入用户模型。从您的other_info
kwargs 来看,您可能想提及您的示例使用自定义用户模型。
这是为了说明的目的,可以随意将您的特定用户模型拥有的任何信息放在这里......但请确定是否有人真的有“other_info”,这将是一个自定义用户模型。【参考方案6】:
创建用户执行:
$ python manage.py shell
>>>> from django.contrib.auth.models import User
>>>> user = User.objects.create_user('USERNAME', 'MAIL_NO_REQUIRED', 'PASSWORD')
【讨论】:
【参考方案7】:有几种方法可以从 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()
这将存储纯文本密码。由于您直接修改属性,因此没有应用散列/加密。
【讨论】:
user = User(username="django", password = "secret")
将不会按您的预期工作。请在分享之前验证建议。
嘿,我只是错过了在第一条语句之后调用 save() 。这里还有什么问题吗?
您的第一个和第三个示例导致了一个无用的用户对象。为 django User 对象设置密码的唯一正确方法是: 1 - 在现有的 User 对象上调用 set_password
2 - 使用 User.objects.create_user
辅助函数创建 User 对象使用这两种方法,您可以以相同的方式传递密码形成身份验证用户将输入它,确保哈希匹配将在他们下次尝试登录时起作用。如果您使用其他两个示例设置密码,用户将永远无法登录,因为哈希检查永远不会通过.
那是对的人。添加此示例的目的是让提问者知道我们什么时候可以期待纯文本密码。请阅读这个问题,看看它是否有意义。以上是关于如何从 django shell 创建用户的主要内容,如果未能解决你的问题,请参考以下文章