在这篇文章中,我们将带领您了解如何在mongodb中扩展django的默认用户?的全貌,包括mongodbdjango的相关情况。同时,我们还将为您介绍有关18_django的用户模型和扩展djang
在这篇文章中,我们将带领您了解如何在mongodb中扩展django的默认用户?的全貌,包括mongodb django的相关情况。同时,我们还将为您介绍有关18_django的用户模型和扩展django的用户模型、django from组件 ,model—from,django的缓存机制,dango的信号,django的序列号、Django如何在Django表单中自动保存用户?、Django:如何在model.py页面上获取用户ID并动态设置默认值的知识,以帮助您更好地理解这个主题。
本文目录一览:- 如何在mongodb中扩展django的默认用户?(mongodb django)
- 18_django的用户模型和扩展django的用户模型
- django from组件 ,model—from,django的缓存机制,dango的信号,django的序列号
- Django如何在Django表单中自动保存用户?
- Django:如何在model.py页面上获取用户ID并动态设置默认值
如何在mongodb中扩展django的默认用户?(mongodb django)
使用EmbeddedField
并不是一个好主意,因为它将复制数据库中的用户数据。您将在“用户”集合中有一些用户,并且相同的数据将嵌入到Profile
集合元素中。
只需将用户ID保留在模型中并分别查询:
class Profile(models.Model):
user_id = models.CharField() #or models.TextField()
mobile = models.PositiveIntegerField()
address = models.CharField(max_length=200)
pincode = models.PositiveIntegerField()
,
它很简单,如文档中所定义。
所以,首先,使用 djongo 模型作为 model_container
,我认为 User 模型是 Django 模型,而不是 djongo 模型。
第二件事,通过在下面给出的 Meta 类中定义,使您的 model_cotainer
模型抽象。
from djongo import models
class Blog(models.Model):
name = models.CharField(max_length=100)
class Meta:
abstract = True
class Entry(models.Model):
blog = models.EmbeddedField(
model_container=Blog
)
headline = models.CharField(max_length=255)
参考:https://www.djongomapper.com/get-started/#embeddedfield
18_django的用户模型和扩展django的用户模型
[TOC]
User 模型
User
模型是这个框架的核心部分。他的完整的路径是在django.contrib.auth.models.User
。以下对这个User
模型做一个简单的了解:
字段:
内置的User
模型拥有以下的字段: 1. username
: 用户名。150个字符以内。可以包含数字和英文字符,以及_/@/+/.和-
字符。不能为空,且必须唯一。 2. email
: 邮箱。 可以为空。 3. password
: 密码。经过哈希过后的密码. 4. groups
: 分组。多对多的组。一个分组可以拥有多个用户,groups
这个字段是跟Group
的一种多对多的关系. 5. user_permissions
: 权限。一个用户可以拥有多个权限,一个权限可以被多个用户所有用。和Permission
属于一种多对多的关系。 6. is_staff
: 是否可以进入到admin
的站点。代表是否是员工。 7. is_active
: 是否是可用的。对于一些想要删除账号的数据,我们设置值为False
就可以了,而不是真正的从数据库中删除. 8. is_superuser
: 是否是超级管理员。如果是超级管理员,那么拥有整个网站的所有权限. 9. last_login
: 上次登录的时间 10. date_joined
: 注册时间,即账号创建的时间
User模型的基本用法
创建用户:
通过 create_user
方法可以快速的创建用户。这个方法必须传递 username
, password和email可传可不传 示例代码如下。
from django.contrib.auth.models import User
user = User.objects.create_user(username=''long'', email=''1987719593@qq.com'', password=''111111'')
# 创建完成后,还可以进行修改某个字段, 如
user.password = ''yanyan_love''
user.save()
创建超级用户:
创建超级用户有两种方式。第一种是使用代码的方式。用代码创建超级用户跟创建普通用户非常的类似,只不过是使用 create_superuser
, 并且必须要传递username, password, email
。示例代码如下:
from django.contrib.auth.models import User
user = User.objects.create_superuser(username=''long'', email=''1987719593@qq.com'', password=''111111'')
也可以通过命令行的方式。命令为: python manage.py create_superuser
, 然后根据提示输入用户名和邮箱和密码
我的创建用户代码
# User 模型的基本用法
# 1. 创建用户
from django.contrib.auth.models import User
class CreateUser(View):
def get(self, request):
return render(request, ''blog/create_user.html'')
def post(self, request):
username = request.POST.get(''username'')
password = request.POST.get(''password'')
email = request.POST.get(''email'')
print(username, password, email)
if username:
# 1. 创建普通用户
user = User.objects.create_user(username=username)
# 创建完成后,还可以对某个字段进行修改
user.password = ''5201314'' # 这样子修改的密码是不加密的
user.email = ''haolong@163.com''
user.save()
# if username and email and password:
# 2. 创建超级用户,代码实现
# super_user = User.objects.create_superuser(username=username, email=email, password=password)
return HttpResponse(''success'')
return HttpResponse(''fail'')
修改密码:
因为密码是需要经过加密后才能存储进去的,所以如果想要修改密码,不能直接修改 password
字段。而需要调用 set_password
来达到修改密码的目的。 示例代码如下:
# 修改密码
from django.contrib.auth.models import User
def set_password_user(request):
user = User.objects.get(pk=1)
user.set_password(''new_password'') # 把新的密码放在括号中
user.save() # 记得保存
return HttpResponse(''success'')
登录验证
Django的验证系统已经帮我们实现了登录验证的功能。通过 django.contrib.auth.authenticate
即可实现。这个方法只能通过 username
和 password
来进行验证。示例代码如下:
# 登录验证
from django.contrib.auth import authenticate
def login(request):
# user = authenticate(username=''yan'', password=''adminadmin'')
user = authenticate(request, username=''yan'', password=''adminadmin'')
print(user)
# 如果验证通过了,就会返回一个 user 对象
if user:
# 验证通过后的代码
print(''登录成功: %s'' % user.username)
else:
# 验证失败后的代码
print(''登录失败 用户名或密码错误'')
return HttpResponse(''login'')
扩展用户模型:
Django 内置的 User
模型虽然已经足够强大了,但是有时候还是不能满足我们的需求。比如在验证用户登录的时候,他用的是用户名作为验证,而我们有时候需要通过手机号码或者邮箱来进行验证。还有比如我们想要增加一些新的的字段。那么这时候我们就需要扩展用户模型了。扩展用户模型有多种方式。这里我们一一讨论下。
1. 设置Proxy
模型
如果你对 Django
提供的字段,以及验证的方法都比较满意,没有什么需要修改的,只是需要在他原有的基础之上增加一些操作的方法,那么建议使用这种方式。示例代码如下:
from django.db import models
from django.contrib.auth.models import User
class Person(User):
class Meta:
proxy = True
def get_blacklist(self):
return self.objects.filter(is_active=False) # is_active 是否激活,判断该用户是否可用,=False即不可用
# models.py
from django.contrib.auth.models import User
# User 的代理模型
class Person(User):
# 这种Field字段不可以有,有的话,数据库映射的时候会报错, 需要注意
# telephone = models.CharField(max_length=11)
class Meta:
proxy = True
@classmethod
def get_blacklist(cls):
"""获取所有的黑名单"""
return cls.objects.filter(is_active=False)
# 不止可以定义这些,还可以定义一些其它的
# 使用 views.py
# 扩展用户模型
from .models import Person
def proxy_view(request):
blacklist = Person.get_blacklist() # 获取所有没有激活的用户, 即黑名单用户
for person in blacklist:
print(person.username)
return HttpResponse(''proxy 扩展用户模型'')
# 如果没有未激活的用户, 可以设置用户为未激活
def set_active(reqeust):
"""设置黑名单用户"""
user = User.objects.get(pk=1)
user.is_active = 0
user.save()
return HttpResponse(''设置黑名单成功: %s'' % user.username)
在以上,我们定义了一个Person
对象,让他继承自 User
, 并且在 Meta
元类中设置了 proxy=True
,说明这个Person 只是 User
的一个代理模型。他并不会影响原来 User
模型在数据库中表的结构,以后如果你想方便的获取所有黑名单的人,那么你就可以通过 Person.get_blacklist()
就可以获取到。并且 User.objects.all()
和Person.objects.all
其实是等价的,加为他们都是从User
这个模型中获取所有的数据 (注意: 如果一个模型是代理模型, 那么就不能在这个模型中添加新的Field
)
2. 一对一外键
如果你对用户验证方法 authenticate
没有其他要求,就是使用 username
和 password
即可完成。但是想要在原来模型的基础上添加新的字段,那么可以使用 一对一外键
的方式。示例代码如下:
# models.py
# 一对一外键 扩展用户模型
from django.contrib.auth.models import User
from django.db import models
from django.dispatch import receiver
from django.db.models.signals import post_save
class UserExtension(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name=''extension'')
telephone = models.CharField(max_length=11, verbose_name=''电话号码'')
birthday = models.DateField(null=True, blank=True, verbose_name=''出生日期'')
school = models.CharField(max_length=20, verbose_name=''学校'')
@receiver(post_save, sender=User)
def create_user_extension(sender, instance, created, **kwargs):
if created:
UserExtension.objects.create(user=instance)
else:
instance.extension.save()
# 使用 views.py
# 一对一扩展 User 模型
def one_to_one_user(request):
user = User.objects.create_superuser(username=''yy'', password=''5021314yanyan'', email=''1599962587@qq.com'')
user.extension.telephone = ''13037200197''
user.extension.school = ''明瑞''
user.save()
return HttpResponse(''一对一扩展User用户模型'')
# 自定义字段验证登录
# 自定义验证登录
def my_authenticate(telephone, password):
user = User.objects.filter(extension__telephone=telephone).first()
print(user)
if user:
is_correct = user.check_password(password)
print(is_correct)
if is_correct:
return user
else:
return None
else:
return None
def one_login(request):
"""使用自定义的验证 my_authenticate 来进行登录验证"""
telephone = request.GET.get(''telephone'')
password = request.GET.get(''password'')
user = my_authenticate(telephone, password)
print(user)
if user:
print(''验证成功: %s'' % user.username)
else:
print(''验证失败'')
return HttpResponse(''自定义验证字段登录'')
以上定义了一个 UserExtension
的模型,并且让他和 User
模型进行了一对一
的绑定,以后我们新增的字段,就添加到 UserExtension
上。 并且还写了一个接受保存模型的信号处理方法,只要是 User
调用了save()
方法,那么就会创建一个UserExtension
和 User
进行绑定。
3. 继承自 AbstractUser
:
对于 authenticate
不满意,并且不想要修改原来的 User
对象上的一些字段,但是想要增加一些字段,那么这时候可以直接继承自django.contrib.auth.models.AbstractUser
,其实这个类也是 django.contrib.auth.models.User
的父类。比如我们想要在原来 User
模型的基础之上添加一个 telephone
和 school
字段。 示例代码如下: (注意: 第一次映射数据库的时候就要创建好)
# models.py
# 继承自 AbstractUser
from django.contrib.auth.models import BaseUserManager
class UserManager(BaseUserManager):
use_in_migrations = True
def _create_user(self, telephone, username, password, **extra_fields):
if not telephone:
raise ValueError(''必须要传递手机号码'')
if not password:
raise ValueError(''必须要传递手机号码'')
user = self.model(telephone=telephone, *extra_fields)
user.set_password(password)
user.save()
return user
def create_user(self, telephone, username, password, **kwargs):
kwargs[''is_superuser''] = False
return self._create_user(telephone=telephone, username=username, password=password, **kwargs)
def create_superuser(self, telephone, username, password, **kwargs):
kwargs[''is_superuser''] = True
return self._create_user(telephone=telephone, username=username, password=password, **kwargs)
# 继承自 AbstractUser
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
telephone = models.CharField(max_length=11, unique=True, verbose_name=''电话号码'')
school = models.CharField(max_length=100)
# 指定 telephone 作为 USERNAME_FIELD, 以后使用 authenticate
# 函数验证的时候,就可以根据 telephone 来验证
# 而不是原来的 username
USERNAME_FIELD = ''telephone''
REQUIRED_FIELDS = []
objects = UserManager()
# settings.py
# 并且在 settins.py 中添加这样一句话:
AUTH_USER_MODEL = ''blog.User'' # blog 是 app 名字, User 是blog.models 下面新建的一个类,即上面那个
from django.contrib.auth.models import AbstractUser, UserManager as _UserManager
class UserManager(_UserManager):
""""""
# def create_superuser(self, username, mobile, password, email=None, **extra_fields):
# super().create_superuser(username=username, mobile=mobile, password=password, email=None, **extra_fields)
def create_superuser(self, username, password, email=None, **extra_fields):
super().create_superuser(username=username, password=password, email=email, **extra_fields)
class Users(AbstractUser):
"""
add mobile 、 email_active fields to Django uswers models
"""
mobile = models.CharField(max_length=11, unique=True, verbose_name=''手机号'', help_text=''手机号'', error_messages={
''unique'': ''此手机号已经被注册过了'',
})
email_active = models.BooleanField(default=False, verbose_name=''邮箱验证状态'')
REQUIRED_FIELDS = [''mobile'']
objects = UserManager() # objects 管理器 UserManager
class Meta:
db_table = ''tb_users''
verbose_name = ''用户''
verbose_name_plural = verbose_name
def __str__(self):
return self.username
4. 继承自 AbstractBaseUser 模型:
如果你想修改默认的验证方式,并且对于原来 User
模型上的一些字段不想要,那么可以自定义一个模型,然后继承自 AbstractBaseUser
,再添加你想要的字段。这种方式会比较麻烦,最好是确定自己对 Django 比较才推荐使用。
完整例子:
from django.db import models
from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin, BaseUserManager
from shortuuidfield import ShortUUIDField
# 用户管理器
class UserManager(BaseUserManager):
"""
自定义用户管理器
"""
def _create_user(self, telephone, username, password, **kwargs):
if not telephone:
raise ValueError(''请传入手机号码'')
if not username:
raise ValueError(''请传入用户名'')
if not password:
raise ValueError(''请传入密码'')
user = self.model(telephone=telephone, username=username, **kwargs)
user.set_password(password)
return user
def create_user(self, telephone, username, password, **kwargs):
"""创建普通用户"""
kwargs[''is_superuser''] = False
return self._create_user(telephone, username, password, **kwargs)
def create_superuser(self, telephone, username, password, **kwargs):
"""创建超级用户"""
kwargs[''is_superuser''] = True
return self._create_user(telephone, username, password, **kwargs)
# 定义用户模型
class User(AbstractBaseUser):
# 我们不使用默认的自增长的主键
# uuid/shortuuid
# shortuuidfield: pip install django-shortuuidfield
uid = ShortUUIDField(primary_key=True, verbose_name=''以uuid作为主键,不使用默认的主键'')
telephone = models.CharField(max_length=11, unique=True, verbose_name=''手机号'', help_text=''手机号'')
# password = models.CharField(max_length=200, verbose_name=''密码'', help_text=''密码'')
email = models.EmailField(unique=True, verbose_name=''邮箱'', help_text=''邮箱'')
username = models.CharField(max_length=100, unique=True, verbose_name=''用户名'', help_text=''用户名'')
is_active = models.BooleanField(default=True, verbose_name=''是否是可用的, 默认是可用的,即默认该用户就是激活了的'', help_text=''该用户是否是可用的'')
is_staff = models.BooleanField(default=False, verbose_name=''是否是员工, 即是否能够登录到后台'', help_text=''是否是员工'')
join_time = models.DateTimeField(auto_now_add=True, verbose_name=''用户加入时间'')
USERNAME_FIELD = ''telephone''
REQUIRED_FIELDS = [''username'']
EMAIL_FIELD = ''email''
# 用户管理器
objects = UserManager()
def get_full_name(self):
return self.username
def get_short_name(self):
return self.username
class Meta:
db_table = ''cms_user''
verbose_name = ''用户''
verbose_name_plural = verbose_name
django from组件 ,model—from,django的缓存机制,dango的信号,django的序列号
1.构建一个表单
假设你想在你的网站上创建一个简单的表单,以获得用户的名字。你需要类似这样的模板:
1
2
3
4
5
|
<form
action
=
"/your-name/"
method=
"post"
>
<label
for
=
"your_name"
>Your
name
: </label>
<input id=
"your_name"
type=
"text"
name
=
"your_name"
>
<input type=
"submit"
value=
"OK"
>
</form>
|
这是一个非常简单的表单。实际应用中,一个表单可能包含几十上百个字段,其中大部分需要预填充,而且我们预料到用户将来回编辑-提交几次才能完成操作。
我们可能需要在表单提交之前,在浏览器端作一些验证。我们可能想使用非常复杂的字段,以允许用户做类似从日历中挑选日期这样的事情,等等。
这个时候,让Django 来为我们完成大部分工作是很容易的。
so,两个突出优点:
1 form表单提交时,数据出现错误,返回的页面中仍可以保留之前输入的数据。
2 方便地限制字段条件
2.在Django 中构建一个表单
Form 类
我们已经计划好了我们的 HTML 表单应该呈现的样子。在Django 中,我们的起始点是这里:
1
2
3
4
5
6
|
#forms.py
from django import forms
class NameForm(forms.Form):
your_name = forms.CharField(label= ''Your name'' , max_length=100)
|
它定义一个Form
类,只带有一个字段(your_name
)。
字段允许的最大长度通过max_length
定义。它完成两件事情。首先,它在HTML 的<input>
上放置一个maxlength="100"
(这样浏览器将在第一时间阻止用户输入多于这个数目的字符)。它还意味着当Django 收到浏览器发送过来的表单时,它将验证数据的长度。
Form
的实例具有一个is_valid()
方法,它为所有的字段运行验证的程序。当调用这个方法时,如果所有的字段都包含合法的数据,它将:
- 返回
True
- 将表单的数据放到
cleaned_data
属性中。
完整的表单,第一次渲染时,看上去将像:
1
2
|
<label for = "your_name" >Your name : </label>
<input id= "your_name" type= "text" name = "your_name" maxlength= "100" >
|
注意它不包含 <form>
标签和提交按钮。我们必须自己在模板中提供它们。
视图:
发送给Django 网站的表单数据通过一个视图处理,一般和发布这个表单的是同一个视图。这允许我们重用一些相同的逻辑。
当处理表单时,我们需要在视图中实例化它:
如果访问视图的是一个GET
请求,它将创建一个空的表单实例并将它放置到要渲染的模板的上下文中。这是我们在第一个访问该URL 时预期发生的情况。
如果表单的提交使用POST
请求,那么视图将再次创建一个表单实例并使用请求中的数据填充它:form = NameForm(request.POST)
。这叫做”绑定数据至表单“(它现在是一个绑定的表单)。
我们调用表单的is_valid()
方法;如果它不为True
,我们将带着这个表单返回到模板。这时表单不再为空(未绑定),所以HTML 表单将用之前提交的数据填充,然后可以根据要求编辑并改正它。
如果is_valid()
为True
,我们将能够在cleaned_data
属性中找到所有合法的表单数据。在发送HTTP 重定向给浏览器告诉它下一步的去向之前,我们可以用这个数据来更新数据库或者做其它处理
Django Form 类详解:
绑定的和未绑定的表单实例
绑定的和未绑定的表单 之间的区别非常重要:
- 未绑定的表单没有关联的数据。当渲染给用户时,它将为空或包含默认的值。
- 绑定的表单具有提交的数据,因此可以用来检验数据是否合法。如果渲染一个不合法的绑定的表单,它将包含内联的错误信息,告诉用户如何纠正数据。
-
-
-
-
字段详解
-
考虑一个比上面的迷你示例更有用的一个表单,我们完成一个更加有用的注册表单:
-
#forms.py from django import forms class RegisterForm(forms.Form): username = forms.CharField(max_length=100, error_messages={"min_length":"最短为5个字符","required":"该字段不能为空"}, ) password = forms.CharField(max_length=100, widget=widgets.PasswordInput(attrs={"placeholder":"password"}) ) telephone=forms.IntegerField( error_messages={ "invalid":"格式错误" } ) gender=forms.CharField( initial=2, widget=widgets.Select(choices=((1,''上海''),(2,''北京''),)) ) email = forms.EmailField() is_married = forms.BooleanField(required=False)
orms.py from django import forms class RegisterForm(forms.Form): username = forms.CharField(max_length=100, error_messages={"min_length":"最短为5个字符","required":"该字段不能为空"}, ) password = forms.CharField(max_length=100, widget=widgets.PasswordInput(attrs={"placeholder":"password"}) ) telephone=forms.IntegerField( error_messages={ "invalid":"格式错误" } ) gender=forms.CharField( initial=2, widget=widgets.Select(choices=((1,''上海''),(2,''北京''),)) ) email = forms.EmailField() is_married = forms.BooleanField(required=False)
Widgets
每个表单字段都有一个对应的
Widget
类,它对应一个HTML 表单Widget
,例如<input type="text">
。在大部分情况下,字段都具有一个合理的默认Widget。例如,默认情况下,
CharField
具有一个TextInput Widget
,它在HTML 中生成一个<input type="text">
。字段的数据
不管表单提交的是什么数据,一旦通过调用
is_valid()
成功验证(is_valid()
返回True
),验证后的表单数据将位于form.cleaned_data
字典中。这些数据已经为你转换好为Python 的类型。注:此时,你依然可以从
request.POST
中直接访问到未验证的数据,但是访问验证后的数据更好一些。在上面的联系表单示例中,is_married将是一个布尔值。类似地,
IntegerField
和FloatField
字段分别将值转换为Python 的int
和float
。回到顶部使用表单模板
你需要做的就是将表单实例放进模板的上下文。如果你的表单在
Contex
t 中叫做form
,那么{{ form }}
将正确地渲染它的<label>
和<input>
元素。表单渲染的选项
对于
<label>/<input>
对,还有几个输出选项:{{ form.as_table }}
以表格的形式将它们渲染在<tr>
标签中{{ form.as_p }}
将它们渲染在<p>
标签中{{ form.as_ul }}
将它们渲染在<li>
标签中
注意,你必须自己提供
<table>
或<ul>
元素。{{ form.as_p }}
会渲染如下: -
<form action=""> <p> <label for="id_username">Username:</label> <input id="id_username" maxlength="100" name="username" type="text" required=""> </p> <p> <label for="id_password">Password:</label> <input id="id_password" maxlength="100" name="password" placeholder="password" type="password" required=""> </p> <p> <label for="id_telephone">Telephone:</label> <input id="id_telephone" name="telephone" type="number" required=""> </p> <p> <label for="id_email">Email:</label> <input id="id_email" name="email" type="email" required=""> </p> <p> <label for="id_is_married">Is married:</label> <input id="id_is_married" name="is_married" type="checkbox"> </p> <input type="submit" value="注册"> </form>
-
手工渲染字段:
我们没有必要非要让Django 来分拆表单的字段;如果我们喜欢,我们可以手工来做(例如,这样允许重新对字段排序)。每个字段都是表单的一个属性,可以使用
{{ form.name_of_field }}
访问,并将在Django 模板中正确地渲染。例如:12345<
div
>
{{ form.Username.errors }}
{{ form.Username.label_tag }}
{{ form.Username }}
</
div
>
渲染表单的错误信息
1、
123registerForm=RegisterForm(request.POST)
print(type(registerForm.errors)) #<
class
''django.forms.utils.ErrorDict''>
print(type(registerForm.errors["username"])) #<
class
''django.forms.utils.ErrorList''>
2、
使用
{{ form.name_of_field.errors }}
显示表单错误的一个清单,并渲染成一个ul
。看上去可能像:123<
ul
>
<
li
>Sender is required.</
li
>
</
ul
>
form组件的钩子
def foo(request): if request.method=="POST": regForm=RegForm(request.POST) if regForm.is_valid(): pass # 可用数据: regForm.cleaned_data, # 将数据插入数据库表中 else: pass # 可用数据: regForm.errors # 可以利用模板渲染讲errors嵌套到页面中返回 # 也可以打包到一个字典中,用于ajax返回 else: regForm=RegForm() return render(request,"register.html",{"regForm":regForm}) '''''' 实例化时: self.fields={ "username":"字段规则对象", "password":"字段规则对象", } is_valid时: self._errors = {} self.cleaned_data = {} #局部钩子: for name, field in self.fields.items(): try: value = field.clean(value) self.cleaned_data[name] = value if hasattr(self, ''clean_%s'' % name): value = getattr(self, ''clean_%s'' % name)() self.cleaned_data[name] = value except ValidationError as e: self.add_error(name, e) # 全局钩子: self.clean() # def self.clean():return self.cleaned_data return not self.errors # True或者False
-
-
-
-
form组件补充
1、Django内置字段如下:


复制代码
Field
required=True, 是否允许为空
widget=None, HTML插件
label=None, 用于生成Label标签或显示内容
initial=None, 初始值
help_text='''', 帮助信息(在标签旁边显示)
error_messages=None, 错误信息 {''required'': ''不能为空'', ''invalid'': ''格式错误''}
show_hidden_initial=False, 是否在当前插件后面再加一个隐藏的且具有默认值的插件(可用于检验两次输入是否一直)
validators=[], 自定义验证规则
localize=False, 是否支持本地化
disabled=False, 是否可以编辑
label_suffix=None Label内容后缀
CharField(Field)
max_length=None, 最大长度
min_length=None, 最小长度
strip=True 是否移除用户输入空白
IntegerField(Field)
max_value=None, 最大值
min_value=None, 最小值
FloatField(IntegerField)
...
DecimalField(IntegerField)
max_value=None, 最大值
min_value=None, 最小值
max_digits=None, 总长度
decimal_places=None, 小数位长度
BaseTemporalField(Field)
input_formats=None 时间格式化
DateField(BaseTemporalField) 格式:2015-09-01
TimeField(BaseTemporalField) 格式:11:12
DateTimeField(BaseTemporalField)格式:2015-09-01 11:12
DurationField(Field) 时间间隔:%d %H:%M:%S.%f
...
RegexField(CharField)
regex, 自定制正则表达式
max_length=None, 最大长度
min_length=None, 最小长度
error_message=None, 忽略,错误信息使用 error_messages={''invalid'': ''...''}
EmailField(CharField)
...
FileField(Field)
allow_empty_file=False 是否允许空文件
ImageField(FileField)
...
注:需要PIL模块,pip3 install Pillow
以上两个字典使用时,需要注意两点:
- form表单中 enctype="multipart/form-data"
- view函数中 obj = MyForm(request.POST, request.FILES)
URLField(Field)
...
BooleanField(Field)
...
NullBooleanField(BooleanField)
...
ChoiceField(Field)
...
choices=(), 选项,如:choices = ((0,''上海''),(1,''北京''),)
required=True, 是否必填
widget=None, 插件,默认select插件
label=None, Label内容
initial=None, 初始值
help_text='''', 帮助提示
ModelChoiceField(ChoiceField)
... django.forms.models.ModelChoiceField
queryset, # 查询数据库中的数据
empty_label="---------", # 默认空显示内容
to_field_name=None, # HTML中value的值对应的字段
limit_choices_to=None # ModelForm中对queryset二次筛选
ModelMultipleChoiceField(ModelChoiceField)
... django.forms.models.ModelMultipleChoiceField
TypedChoiceField(ChoiceField)
coerce = lambda val: val 对选中的值进行一次转换
empty_value= '''' 空值的默认值
MultipleChoiceField(ChoiceField)
...
TypedMultipleChoiceField(MultipleChoiceField)
coerce = lambda val: val 对选中的每一个值进行一次转换
empty_value= '''' 空值的默认值
ComboField(Field)
fields=() 使用多个验证,如下:即验证最大长度20,又验证邮箱格式
fields.ComboField(fields=[fields.CharField(max_length=20), fields.EmailField(),])
MultiValueField(Field)
PS: 抽象类,子类中可以实现聚合多个字典去匹配一个值,要配合MultiWidget使用
SplitDateTimeField(MultiValueField)
input_date_formats=None, 格式列表:[''%Y--%m--%d'', ''%m%d/%Y'', ''%m/%d/%y'']
input_time_formats=None 格式列表:[''%H:%M:%S'', ''%H:%M:%S.%f'', ''%H:%M'']
FilePathField(ChoiceField) 文件选项,目录下文件显示在页面中
path, 文件夹路径
match=None, 正则匹配
recursive=False, 递归下面的文件夹
allow_files=True, 允许文件
allow_folders=False, 允许文件夹
required=True,
widget=None,
label=None,
initial=None,
help_text=''''
GenericIPAddressField
protocol=''both'', both,ipv4,ipv6支持的IP格式
unpack_ipv4=False 解析ipv4地址,如果是::ffff:192.0.2.1时候,可解析为192.0.2.1, PS:protocol必须为both才能启用
SlugField(CharField) 数字,字母,下划线,减号(连字符)
...
UUIDField(CharField) uuid类型
...
2、Django内置插件:


TextInput(Input)
NumberInput(TextInput)
EmailInput(TextInput)
URLInput(TextInput)
PasswordInput(TextInput)
HiddenInput(TextInput)
Textarea(Widget)
DateInput(DateTimeBaseInput)
DateTimeInput(DateTimeBaseInput)
TimeInput(DateTimeBaseInput)
CheckboxInput
Select
NullBooleanSelect
SelectMultiple
RadioSelect
CheckboxSelectMultiple
FileInput
ClearableFileInput
MultipleHiddenInput
SplitDateTimeWidget
SplitHiddenDateTimeWidget
SelectDateWidget
复制代码
3、常用选择插件:


# 单radio,值为字符串
# user = fields.CharField(
# initial=2,
# widget=widgets.RadioSelect(choices=((1,''上海''),(2,''北京''),))
# )
# 单radio,值为字符串
# user = fields.ChoiceField(
# choices=((1, ''上海''), (2, ''北京''),),
# initial=2,
# widget=widgets.RadioSelect
# )
# 单select,值为字符串
# user = fields.CharField(
# initial=2,
# widget=widgets.Select(choices=((1,''上海''),(2,''北京''),))
# )
# 单select,值为字符串
# user = fields.ChoiceField(
# choices=((1, ''上海''), (2, ''北京''),),
# initial=2,
# widget=widgets.Select
# )
# 多选select,值为列表
# user = fields.MultipleChoiceField(
# choices=((1,''上海''),(2,''北京''),),
# initial=[1,],
# widget=widgets.SelectMultiple
# )
# 单checkbox
# user = fields.CharField(
# widget=widgets.CheckboxInput()
# )
# 多选checkbox,值为列表
# user = fields.MultipleChoiceField(
# initial=[2, ],
# choices=((1, ''上海''), (2, ''北京''),),
# widget=widgets.CheckboxSelectMultiple
# )
Django如何在Django表单中自动保存用户?
如何解决Django如何在Django表单中自动保存用户??
当我将“用户”字段传递给我的模型表单时。我正在获取所有用户详细信息作为下拉列表。看图:
我试图在不显示此下拉列表的情况下保存当前用户实例,因为我希望用户将在不选择或显示此下拉列表的情况下自动保存。
这是我的 forms.py 文件:
class ProfileFroms(forms.ModelForm):
class Meta:
model = UserProfile
fields = ["user","profile_pic","mobile","country","website_link"]
当我从字段中删除“用户”时,出现此错误:
"NOT NULL constraint Failed: members_userprofile.user_id"
我也试过这个代码来保存当前用户,但它给我带来了同样的错误。
views.py
if forms.is_valid():
forms.user = request.user
这是我的完整代码:
models.py
class UserManagement(AbstractUser):
is_subscriber = models.BooleanField(default=False)
is_customer = models.BooleanField(default=False)
class UserProfile(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL,on_delete=models.CASCADE,related_name="userprofile")
profile_pic = models.ImageField(upload_to=''profile/images/'',validators=[validate_file_size,FileExtensionValidator( [''png'',''jpg''] )],blank=True,null=True)
mobile = models.IntegerField(blank=True,null=True)
country = models.CharField(max_length=200,null=True)
website_link = models.CharField(max_length=3000,null=True)
views.py
def UserProfileView(request):
userinfo = UserManagement.objects.filter(username=request.user)
forms = ProfileFroms(request.POST,request.FILES or None)
if request.method == "POST":
if forms.is_valid():
#forms.user = request.user #tried this line for save current user but didn''t work
forms.save()
messages.add_message(request,messages.INFO,''Profile updated sucessfully'')
return redirect("members:user-profile-private")
else:
messages.add_message(request,''Somethings wrong. Profile not updated'')
print("invalid")
context={"userinfo":userinfo,"forms":forms}
return render(request,"members/privateprofile.html",context)
解决方法
从表单中删除 user
字段:
class ProfileFroms(forms.ModelForm):
class Meta:
model = UserProfile
fields = [''profile_pic'',''mobile'',''country'',''website_link'']
然后您更改表单的 .instance
(不是表单本身),因此:
if forms.is_valid():
forms.instance.user = request.user
forms.save()
Django:如何在model.py页面上获取用户ID并动态设置默认值
如果要通过“管理控制台”进行保存,请尝试以下操作:
class VariablesAdmin(admin.ModelAdmin):
def save_model(self,request,obj,form,change):
obj.user_var_id = request.user.id
super().save_model(request,change)
如果要通过api或视图集进行保存,请尝试以下操作:
variable = Variables()
variable.user_var_id = request.user.id
variable.save()
,
在您的视图内部,request.user.id将始终返回当前用户的ID。您可以在查询中简单地使用它来获取所需的模型。 您还错误地将代码中的“对象”和“获取”都大写,这是不正确的。
因此您的查询应如下所示:
variable = Variables.objects.get(user_var_id=request.user.id)
编辑:您似乎想访问模型文件中的“当前用户”,而不是(逻辑上)访问视图文件中的“当前用户”; request.user.id仅在视图中可用,因为每个视图都收到一个请求。
,所以您想要的是,当用户创建项目时,它将从他们的变量中获取值。
您可以做的是创建一个信号,以便在创建项目时将获得用户和相关字段,并将其添加到项目中,然后保存。
https://docs.djangoproject.com/en/3.1/topics/signals/
,#to get request in models.py
from crequest.middleware import CrequestMiddleware
current_request = CrequestMiddleware.get_request()
pip install django-crequest
第1步:在您的settings.py中将crequest添加到INSTALLED_APPS
步骤2:在身份验证和会话中间件之后,将crequest.middleware.CrequestMiddleware添加到MIDDLEWARE_CLASSES。
今天关于如何在mongodb中扩展django的默认用户?和mongodb django的讲解已经结束,谢谢您的阅读,如果想了解更多关于18_django的用户模型和扩展django的用户模型、django from组件 ,model—from,django的缓存机制,dango的信号,django的序列号、Django如何在Django表单中自动保存用户?、Django:如何在model.py页面上获取用户ID并动态设置默认值的相关知识,请在本站搜索。
本文标签: