django rest framework - 在不更改现有代码的情况下扩展 auth.user
django rest framework - extending the auth.user without changing existing code
我正在使用 django rest 框架并构建一个 RESTful api 以从 android 应用程序访问。
我想扩展用户模型并添加一个 phone 数字字段 - 但我的模型带有用户模型的外键以及基于令牌的身份验证。
例如:
class Ride(models.Model):
driver = models.ForeignKey('auth.User')
destination=models.ForeignKey(Destination)
显然我有默认用户 table 并且正如我所说 - 令牌身份验证 - (在 注册 上生成令牌,然后在客户端 登录 - 发送 username:password 并获取 token 登录)。
我的问题是:
如何以 最小更改 为 code/models/views 并以最佳方式将此字段添加到用户?我看了很多关于这个主题的答案,只是想使用最好的选择。
------------编辑-------------
添加 UserProfile 后我在创建用户时遇到问题,代码如下:
serializers.py:
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('id', 'username', 'first_name', 'last_name', 'password', )
extra_kwargs = {'password': {'write_only': True}}
def create(self, validated_data):
user = User(
first_name=validated_data['first_name'],
username=validated_data['username'],
last_name=validated_data['last_name']
)
user.set_password(validated_data['password'])
user.save()
user.UserProfile.phone_number = self.initial_data["phone_number"]
return user
Models.py
class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
phone_number = models.CharField(max_length=15)
@receiver(post_save, sender=User)
def handle_user_save(sender, instance=None, created=False, **kwargs):
if created:
UserProfile.objects.create(user=instance)
Token.objects.create(user=instance)
user.save() 调用 handle_user_save 方法 - 然后我创建了 UserProfile。
问题是 - 在我创建它之后 - 我无法从用户那里更新它的字段。问题出在这一行:
user.UserProfile.phone_number = self.initial_data["phone_number"]
它抛出异常 - "User doesn't have field UserProfile"。
我应该怎么做?
谢谢
提到的 OneToOne 字段很可能是指 Django 建议的 Extending the Existing User Model 方式。
建议您创建一个新模型,例如 UserProfile,然后在其中添加您需要的任何新字段。 UserProfile 将 link 到使用 OneToOne 字段的用户模型。
from django.contrib.auth.models import User
class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
new_field = models.CharField(max_length=100)
来自其他模型的所有外键引用仍应指向 Django 的用户模型。当您需要添加的新字段时,您可以从用户那里提取配置文件:
user = Users.objects.get(username='example')
print user.userprofile.new_field
我正在使用 django rest 框架并构建一个 RESTful api 以从 android 应用程序访问。
我想扩展用户模型并添加一个 phone 数字字段 - 但我的模型带有用户模型的外键以及基于令牌的身份验证。
例如:
class Ride(models.Model):
driver = models.ForeignKey('auth.User')
destination=models.ForeignKey(Destination)
显然我有默认用户 table 并且正如我所说 - 令牌身份验证 - (在 注册 上生成令牌,然后在客户端 登录 - 发送 username:password 并获取 token 登录)。
我的问题是:
如何以 最小更改 为 code/models/views 并以最佳方式将此字段添加到用户?我看了很多关于这个主题的答案,只是想使用最好的选择。
------------编辑-------------
添加 UserProfile 后我在创建用户时遇到问题,代码如下:
serializers.py:
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('id', 'username', 'first_name', 'last_name', 'password', )
extra_kwargs = {'password': {'write_only': True}}
def create(self, validated_data):
user = User(
first_name=validated_data['first_name'],
username=validated_data['username'],
last_name=validated_data['last_name']
)
user.set_password(validated_data['password'])
user.save()
user.UserProfile.phone_number = self.initial_data["phone_number"]
return user
Models.py
class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
phone_number = models.CharField(max_length=15)
@receiver(post_save, sender=User)
def handle_user_save(sender, instance=None, created=False, **kwargs):
if created:
UserProfile.objects.create(user=instance)
Token.objects.create(user=instance)
user.save() 调用 handle_user_save 方法 - 然后我创建了 UserProfile。
问题是 - 在我创建它之后 - 我无法从用户那里更新它的字段。问题出在这一行:
user.UserProfile.phone_number = self.initial_data["phone_number"]
它抛出异常 - "User doesn't have field UserProfile"。
我应该怎么做?
谢谢
提到的 OneToOne 字段很可能是指 Django 建议的 Extending the Existing User Model 方式。
建议您创建一个新模型,例如 UserProfile,然后在其中添加您需要的任何新字段。 UserProfile 将 link 到使用 OneToOne 字段的用户模型。
from django.contrib.auth.models import User
class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
new_field = models.CharField(max_length=100)
来自其他模型的所有外键引用仍应指向 Django 的用户模型。当您需要添加的新字段时,您可以从用户那里提取配置文件:
user = Users.objects.get(username='example')
print user.userprofile.new_field