【问题标题】:django rest framework - extending the auth.user without changing existing codedjango rest 框架 - 在不更改现有代码的情况下扩展 auth.user
【发布时间】:2015-10-27 06:57:34
【问题描述】:

我正在使用 django rest 框架并构建一个 RESTful api 以从 android 应用程序访问。

我想扩展用户模型并添加电话号码字段 - 但我的模型带有用户模型的外键以及基于令牌的身份验证。

例如:

class Ride(models.Model):
    driver = models.ForeignKey('auth.User')
    destination=models.ForeignKey(Destination)

显然我有默认用户表,正如我所说 - 令牌身份验证 - (在 register 上生成令牌,然后客户端 login - 发送 username:password 并获得 token 登录)。

我的问题是:

如何以代码/模型/视图最小更改并以最佳方式将此字段添加给用户?我阅读了很多关于这个主题的答案,只是想使用最好的选择。

------------ 编辑 --------------

添加 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"]

它抛出异常 - “用户没有字段 UserProfile”。

我该怎么做?

谢谢

【问题讨论】:

  • 我建议使用onetoone字段。
  • 感谢您的回答。如果我使用 OneToOne 字段,我需要改变什么?你能给我举个例子吗?

标签: django foreign-keys django-rest-framework extending


【解决方案1】:

提到的 OneToOne 字段很可能是指 Django 建议的Extending the Existing User Model 方式。

建议您创建一个新模型,例如 UserProfile,并在其中添加您需要的任何新字段。 UserProfile 将使用 OneToOne 字段链接到 User 模型。

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

【讨论】:

  • 感谢您的回答。因此,如果我使用 OneToOne 字段,我将不得不进行更改——我显然必须更改外键以指向 UserProfile 而不是 auth.user。也在 UserViewSet 中,对吧?我还有一个问题是 - 如果我执行 self.request.user,我会得到 auth.user 还是 UserProfile?再次感谢!
  • @OfekAgmon - 我已经纠正了我的最后一点,它有点错误,可能会让你误入歧途。外键仍应按照您当前的操作方式直接指向用户模型。您可以将 UserProfile 作为 User 对象上的一个字段进行访问,然后从那里访问您添加到 UserProfile 中的任何新字段。
  • 再次感谢。我现在无法注册用户 - 使用代码编辑我的问题。
  • @OfekAgmon - 问题可能与您引用 UserProfile 的方式有关。命名默认反向关系的正确方法是全部小写。 See Docs here.我已经更新了我的答案以反映这一点。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-08
  • 2014-02-27
  • 2023-04-08
  • 2014-02-26
  • 1970-01-01
  • 2011-12-03
相关资源
最近更新 更多