没有与模型相关的字段,如SlugRelatedField到序列化器

时间:2018-12-01 20:07:39

标签: django

我已经添加了一个视图来创建一个新用户,该视图需要用户名,密码,电子邮件和一个子字段来链接到权限。

class CreateUserSerializer(serializers.ModelSerializer):
    group = serializers.SlugRelatedField(queryset=CompanyGroup.objects.all(), slug_field='slug_field')

    class Meta:
        model = User
        fields = ['company', 'email', 'username', 'password', 'token', 'group']
        read_only_fields = ['token']
        write_only_fields = ('password',)

    def create(self, validated_data):
        return User.objects.create_user(**validated_data)

此请求的视图为;

class UserManager(BaseUserManager):

    def get_queryset(self):
        return UserQuerySet(self.model, using=self._db).active_and_not_deleted()

    def create_user(self, username, email, password, group=None, company=None):
        user = self.model(username=username, email=self.normalize_email(email), company=company)
        user.set_password(password)

        return user

我正在尝试使用SlugRelatedField自动链接到在slug字段中传递的Group,并将其传递到模型中的create_user方法。

AttributeError at /users/
Got AttributeError when attempting to get a value for field `group` on serializer `CreateUserSerializer`.
The serializer field might be named incorrectly and not match any attribute or key on the `User` instance.
Original exception text was: 'User' object has no attribute 'group'.

执行此操作时出现异常:

class User(AbstractUser):
    # Date the User was created
    created_at = models.DateTimeField(auto_now_add=True)

    # Date the User info was last updated
    updated_at = models.DateTimeField(auto_now=True)

    # Date the User last logged into the app
    last_active = models.DateTimeField(auto_now=True)

    # The company which this user is associated with.
    company = models.ForeignKey(Company, on_delete=models.CASCADE, null=True)

    # Indicates whether this user has been deleted or not
    is_deleted = models.BooleanField(default=False)

    USERNAME_FIELD = 'username'
    REQUIRED_FIELDS = ['email']

    objects = UserManager()

    def __str__(self):
        return self.username

    @property
    def token(self):
        return self._generate_jwt_token()

    def _generate_jwt_token(self):
        dt = datetime.now() + timedelta(days=60)

        token = jwt.encode({
            'id': self.pk,
            'exp': int(dt.strftime('%s'))
        }, settings.SECRET_KEY, algorithm='HS256')

        return token.decode('utf-8')

我知道此异常确切地说明了我的问题,但我试图避免将其放在User对象上,并从这些对象中手动查找Group。

编辑:

根据要求提供模型;

class CompanyGroup(Group):
    slug_field = models.SlugField()

    objects = GroupManager()

    def __str__(self):
        return self.name

然后分组;

if request.env['omniauth.auth']
  user = User.find_or_create_from_auth_hash(request.env['omniauth.auth'])
  session[:user_id] = user.id
  flash[:failure] = "Facebook login failed "
  redirect_to user

def self.find_or_create_from_auth_hash(auth)
    where(provider: auth.provider, uid: auth.uid).first_or_initialize.tap do |user|
      user.provider = auth.provider
      user.id = auth.uid
      user.fname = auth.info.first_name
      user.lname = auth.info.last_name
      user.email = auth.info.email
      #user.picture = auth.info.image
      user.save!
    end
  end

1 个答案:

答案 0 :(得分:0)

我认为UserGroupCompany之间需要有一个ManyToMany关系(据我从评论中了解)。因为按照documentation

  

SlugRelatedField可用于通过目标上的字段表示关系的目标。

因此,您可以像这样添加它:

class User(AbstractUser):
    # rest of the fields
    group = models.ManyToManyField(GroupCompany)

需要确保slug_fieldGroupCompany中是唯一的:

slug_field = models.SlugField(unique=True)

此外,您还需要更改create_user模型管理器方法:

def create_user(self, username, email, password, company=None):
    user = self.model(username=username, email=self.normalize_email(email), company=company)
    user.set_password(password)
    user.save()
    return user

并更新序列化程序:

class CreateUserSerializer(serializers.ModelSerializer):
    group = serializers.SlugRelatedField(queryset=CompanyGroup.objects.all(), slug_field='slug_field', many=True)  # added many True

    def create(self, validated_data):
        group = validated_data.pop('group')
        user = User.objects.create_user(**validated_data)
        user.group.add(group)
        return user

更新

class CreateUserSerializer(serializers.ModelSerializer):
    company_group = serializers.CharField(write_only=True)  # added many True

    def create(self, validated_data):
        group = validated_data.pop('company_group')
        user = User.objects.create_user(**validated_data)
        group, _ = CompanyGroup.objects.create(slug_field=company_group)
        user.group.add(group)
        return user