django中使用Profile扩展User模块(基于django 1.10版本下)
版本:Django 1.10.1(其他版本可能有不同的实现好解决办法)
参考官方文档:https://docs.djangoproject.com/en/1.10/topics/auth/customizing/
在开发过程中,Django的用户管理模块能够给我们带来非常大的便利,但是Django的User模块所提供的字段太少,所以对User模块的扩展是必须的,下面结合我自己的开发过程中,使用Profile扩展User模块时遇到的问题以及解决的方法进行记录。
先看一段我根据官方文档最先开发完成的代码:
admin.py
from django.contrib import admin
from django.contrib.auth.models import User
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin from models import * class AccountInline(admin.StackedInline):
model = Account
can_delete = False
verbose_name_plural = 'account' class UserAdmin(BaseUserAdmin):
inlines = (AccountInline, ) admin.site.unregister(User)
admin.site.register(User, UserAdmin)
model.py:
from __future__ import unicode_literals from mysite import settings
from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save class Account(models.Model):
"""
Registered users
"""
SEX_CHOICES = {
1: 'boy',
2: 'girl',
} user = models.OneToOneField(User, on_delete=models.CASCADE)
sex = models.SmallIntegerField(default=1, choices=SEX_CHOICES.items())
birth = models.DateField(blank=True, null=True)
age = models.SmallIntegerField(blank=True,null=True)
contact_number = models.CharField(max_length=128, blank=True, null=True)
personalized_signature = models.CharField(max_length=128, blank=True, null=True)
picture = models.ImageField(upload_to="Image/", blank=True,null=True)
openid = models.CharField(max_length=128, blank=True, null=True) def __unicode__(self):
return self.user.username class Meta:
db_table = 'Account' def create_user_profile(sender, instance, created, **kwargs):
if created:
profile = Account()
profile.user = instance
profile.save() post_save.connect(create_user_profile, sender=User)
settings.py:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'Blog'
]
AUTH_PROFILE_MODULE = 'Blog.Account'
这段是官方文档给出的参考方法:可以很好的让你自己的model跟User模块进行一对一的外键映射。
我们可以通过admin页面进行用户的创建,可以看到我们的Account模型很好的嵌入了User模块,然后可以对User模块进行字段的扩张。

但是此时,当你保存的时候,出现了问题,请看截图:

这个问题告诉我(仅仅是我的理解,如果有错误希望留言提出),当django创建完User表中的用户时,通过Userprofile去创建第二个实例(Account)的时候,执行save操作的时候,执行了俩次,从而导致上面的user_id已经存在无法完成操作,这个原因在于:上面model中调用post_save发生了俩次(django自己的save一次,然后通过信号post_save一次,导致第二个调用save的时候发现已经存在了相同的主键ID)
所以我们需要做的就是对model.py文件中的save进行重写,重写之后的model.py文件为:
class Account(models.Model):
"""
Registered users
"""
SEX_CHOICES = {
1: 'boy',
2: 'girl',
} user = models.OneToOneField(User, on_delete=models.CASCADE)
sex = models.SmallIntegerField(default=1, choices=SEX_CHOICES.items())
birth = models.DateField(blank=True, null=True)
age = models.SmallIntegerField(blank=True,null=True)
contact_number = models.CharField(max_length=128, blank=True, null=True)
personalized_signature = models.CharField(max_length=128, blank=True, null=True)
picture = models.ImageField(upload_to="Image/", blank=True,null=True)
openid = models.CharField(max_length=128, blank=True, null=True) def __unicode__(self):
return self.user.username class Meta:
db_table = 'Account' def save(self, *args, **kwargs):
if not self.pk:
try:
p = Account.objects.get(user=self.user)
self.pk = p.pk
except Account.DoesNotExist:
pass super(Account, self).save(*args, **kwargs) def create_user_profile(sender, instance, created, **kwargs):
if created:
profile = Account()
profile.user = instance
profile.save() post_save.connect(create_user_profile, sender=User)
这样就会在save创建的时候,对主键pk进行检测然后保存。
因为我在开发的时候用到了django-rest-framework,所以含有serializer序列化文件,在这里一并给出:
serializers.py:
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ("id", "username", "password", "email", "last_login", "date_joined") class AccountSerializer(serializers.ModelSerializer):
class Meta:
model = Account
fields = ("user_id", "user", "sex", "age", "birth", "picture", "contact_number", "personalized_signature", "openid")
django中使用Profile扩展User模块(基于django 1.10版本下)的更多相关文章
- Django中生成随机验证码(pillow模块的使用)
Django中生成随机验证码 1.html中a标签的设置 <img src="/get_validcode_img/" alt=""> 2.view ...
- 在Django中使用Sentry(Python 3.6.8 + Django 1.11.20 + sentry-sdk 0.13.5)
1. 安装Sentry pip install sentry-sdk==0.13.5 2.在settings.py中配置 sentry_sdk.init( dsn="https://**** ...
- Gradle Android客户端程序打包(基于gradle 2.10版本验证通过)
一.前言 目前正在准备从eclipse开发环境向AndroidStudio迁移,提前过去探探路,不出所料,原来gradle脚本果然报错,无法运行,想想索性把本地的gradle一起升级到最新版本,毕竟1 ...
- Django之csrf中间件及auth模块使用
目录 一.基于配置文件的编程思想 1. importlib 模块 2. 配置文件 二.跨站请求伪造(csrf) 1.csrf简介以及由来 2.Django中的csrf中间件如何使用 2.1 普通for ...
- Django中间件、csrf跨站请求、csrf装饰器、基于django中间件学习编程思想
django中间件 中间件介绍 什么是中间件? 官方的说法:中间件是一个用来处理Django的请求和响应的框架级别的钩子.它是一个轻量.低级别的插件系统,用于在全局范围内改变Django的输入和输出. ...
- Django中载入javascript、css的操作
url.py中的设置: 导入模块 from django.conf import settings (r'^js/(?P<path>.*)$','django.views.static. ...
- Django中的许可(Permissions)和用户组(Group)
Reference: http://www.cnblogs.com/esperyong/archive/2012/12/20/2826690.html 接着上面的3篇讨论文章,我们阐述了Django中 ...
- Django中Middleware中间件
Django中Middleware中间件 1 Middleware中间件概述 django中间middleware实质就是一个类,django会根据自己的规则在合适的时机执行中间件相应的方法.实际上当 ...
- django 中的路由系统(url)
路由系统 根据Django约定,一个WSGI应用里最核心的部件有两个:路由表和视图.Django框架 的核心功能就是路由:根据HTTP请求中的URL,查找路由表,将HTTP请求分发到 不同的视图去处理 ...
随机推荐
- Li-Fi,LED光无线局域网
无需WiFi信号,点一盏LED灯就能上网.昨天,复旦大学计算机科学技术学院传出好消 息,一种利用屋内可见光传输网络信号的国际前沿通讯技术在实验室成功实现.研究人员将网络信号接入一盏1W的LED灯珠,灯 ...
- 一些bug总结
1:IE浏览器低版本的parseInt问题; 开发中遇到把月份转为小数时出现bug 例子:parseInt('08')-1; 本来应该得7,但是最后的结果却是-1,月份得-1,根据得到的月份获取的日历 ...
- java类型占用字节数&类型转换
1.整型类型 存储需求 bit数 取值范围 备注int 4字节 4*8 short ...
- JQuery实现的模块交换动画效果
<!doctype html> <html> <head> <meta http-equiv="content-type" content ...
- [Tomcat 源码分析系列] (一) : Tomcat 启动脚本-startup.bat
概述 我们通常使用 Tomcat 中的 startup.bat 来启动 Tomcat. 但是这其中干了一些什么事呢? 大家都知道一个 Java 程序需要启动的话, 肯定需要 main 方法, 那么这个 ...
- adb无法使用,提示error: unknown host service的解决办法
此时,需要辨别电脑的5037端口被哪个应用程序占用的方法:(使用adb时需要5037端口是空闲的) 1. 打开命令行,输入命令:netstat -ano |findstr "5037&quo ...
- MFC 对话框响应OnChar()
最近在写程序时,出现了对话框里面不接收键盘消息的情况,特别搜索了以下内容 MFC中对话框是不会直接响应OnChar和OnKeyDown消息的,会被 其它控件拦截,测试时发现不会进入这两个函数,必须重定 ...
- 建筑材料系统 ASP.NET MVC4.0 + WebAPI + EasyUI + Knockout 的架构设计开发
框架介绍: 1.基于 ASP.NET MVC4.0 + WebAPI + EasyUI + Knockout 的架构设计开发 2.采用MVC的框架模式,具有耦合性低.重用性高.生命周期成本低.可维护性 ...
- socket网络通信
1.socket通常也称作"套接字",用于描述IP地址和端口.在internet上的主机一般运行了多个服务软件,同时提供几种服务,每种服务都打开一个socket,并绑定到一个端口上 ...
- CSS3 结构伪类选择器 详解
1 CSS3 结构伪类选择器 1.E:root 匹配E元素所在的根元素 即:html 2. E:nth-child(n) (1)匹配E元素的父元素中第n个子元素,(2)且该位置的子元素类型必须是E类型 ...