我使用Django 1.7
和django_rest_framework 3.0
为我的应用程序开发一个安静的后端。
场景: 在客户端上,用户将使用社交网络进行身份验证,比如说facebook。 token
被发送回服务器,该服务器创建并存储Social
模型的实例。
需求: 在保存Social
模型时,我想自动创建并存储{{1}的实例模型。 django.contrib.auth.models User
模型的数据将从用户刚刚通过身份验证的社交网络中提取。
我的方法#1: 我是否可以通过某种方式将合并的json请求发送到我的django后端并创建独立的User
和{{1实例。我认为这需要更改User
(下面给出)代码。
例如(请求发送到我的django):
Social
我的方法#2: 我偶然发现了django框架中的serializers.py
信号。这是我实现post_save()方法的代码
这并不需要像方法#1 这样的组合请求,而是一个由{
'social':{
'token':'XYZ',
'source':'FB',
},
'user_details':{
'first_name':'sahil',
'last_name':'gandhi',
'username':'sahilgandhi',
'email':'sa***com',
'password':'password',
'date_of_birth':'01/01/2015'
}
}
post_save()
如果facebook的回复是这样的话怎么办?
SocialSerializer
我目前的代码如下:
models.py
@receiver(post_save, sender=Social)
def create_user_after_social_signup(sender, instance, created=False, **kwargs):
"""
Automatically create a User instance for every Social signup
:param sender: Social model
:param instance: Social instance that just got created
:param created: is new instance created; boolean
:param kwargs:
:return:
"""
if created:
social = Social.objects.get(pk=instance.id)
# get user details from social (ex: facebook)
payload={'access_token':social.token}
url='https://graph.facebook.com/v2.2/me'
r=requests.get(url, params=payload)
# create user from response using:
# User.objects.create_superuser()
serializer.py
{
"id": "XYZ",
"birthday": "0***4",
"email": "sahi***@gmail.com",
"first_name": "Sahil",
"gender": "male",
"last_name": "Gandhi",
"link": "https://www.facebook.com/app_sco*******632440/",
"location": {
"id": "1*****2",
"name": "M*******a"
},
"locale": "en_US",
"name": "Sahil Gandhi",
"timezone": 5.5,
"updated_time": "2015****00",
"verified": true
}
views.py 普通的基于班级的视图,即class Social(models.Model):
NONE = 'XX'
FACEBOOK = 'FB'
GOOGLEPLUS = 'GP'
TWITTER = 'TW'
LINKEDIN = 'LI'
SOCIAL_NETWORKS = (
(NONE, '------'),
(FACEBOOK, 'Facebook'),
(TWITTER, 'Twitter'),
(GOOGLEPLUS, 'Google Plus'),
(LINKEDIN, 'LinkedIn'),
)
user = models.OneToOneField(User, related_name='social_owner')
token = models.CharField(max_length=250)
# expires_at = models.DateTimeField('token expires at', blank=True, null=True)
source = models.CharField(max_length=2, choices=SOCIAL_NETWORKS,)
class Meta:
db_table = 'user_social'
模型:class SocialSerializer(serializers.ModelSerializer):
class Meta:
model = Social
fields = ('user', 'token', 'source')
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('pk', 'first_name', 'last_name', 'username', 'email', 'date_joined')
和APIView
。
最后: 我强烈认为 方法#1 是更好的方法。只是不知道如何去做。无论哪种方式,你的帮助表示赞赏。