如何在单个表中保存两个表OnetoOne-Django

时间:2018-07-21 23:14:48

标签: django django-models django-rest-framework django-views

我有2个型号:

class User(AbstractUser):
    TYPES = (('A', 'Administrador'), ('P', 'Persona'), ('C', 'Corporativo'), ('E', 'Emprendedor'), ('R', 'Reciclador'))

    login_type = models.CharField(max_length=1, blank=True, null=True)
    account_type = models.CharField(max_length=1, choices=TYPES, blank=True, null=True)
    picture_url = models.CharField(max_length=200, blank=True)
    is_deleted = models.BooleanField(default=False)


class EcoUser(models.Model):
    user = models.OneToOneField(User, related_name='eco_user')
    document = models.CharField(max_length=45, blank=True)
    phone_number = models.CharField(max_length=45, blank=True)
    ubigeo = models.CharField(max_length=6, blank=True)
    address = models.CharField(max_length=500, blank=True)
    location = models.CharField(max_length=200, blank=True)

    def __str__(self):
        return str(self.user)

当我要添加用户时,它也保存在 EcoUser

我认为将两个模型整合到 serializer 中,并使用通用的 create 可以做到:

class UserSerializer(serializers.ModelSerializer):

def to_representation(self, instance):
    representation = super(UserSerializer, self).to_representation(instance)
    eco_user = EcoUser.objects.filter(user_id=instance.id)[0]
    representation['document'] = eco_user.document
    representation['phone_number'] = eco_user.phone_number
    representation['ubigeo'] = eco_user.ubigeo
    representation['address'] = eco_user.address
    return representation


class Meta:
    model = User
    fields = ('id',
              'username',
              'password',
              'first_name',
              'last_name',
              'email',
              'login_type',
              'account_type',
              'picture_url',
              'is_deleted'
              )
    extra_kwargs = {'password': {'write_only': True, 'required': False}}

但是,它只能用于列表,而不能用于创建。 这是我的视图集

class EcoUserViewSet(viewsets.ModelViewSet):
    serializer_class = UserSerializer
    queryset = User.objects.exclude(is_deleted=True)
    pagination_class = None


    @transaction.atomic
    def create(self, request, *args, **kwargs):
        with transaction.atomic():
            try:
                data = request.data
                serializer = self.get_serializer(data=data)
                if serializer.is_valid(raise_exception=True):
                    serializer.save()
                    return Response({"status": True, "results": "Datos guardados correctamente"},
                                    status=status.HTTP_201_CREATED)
            except ValidationError as err:
                return Response({"status": False, "error_description": err.detail}, status=status.HTTP_400_BAD_REQUEST)

我还如何在单个帖子中保存Ecouser数据?

更新 json发送示例:

{
  username: "demo",
  firstname: "demin",
  lastname: "demon"
  login_type: "0",
  #ecouser fields
  account_type: "A",
  document: "74578778",
  phone_number: "54545445",
  ubigeo: "32114",
}

1 个答案:

答案 0 :(得分:1)

您需要两个串行器,一个用于User,另一个用于EcoUser。

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = (your desire fields)
    def create(self, validated_data):
        #codes


class EcoUserSerializer(serializers.ModelSerializer):
    user = UserSerializer()
    class Meta:
        model = EcoUser
        fields = (
           'user',
           other fields
        )
    def create(self, validated_data):
        #codes

然后为EcoUserSerializer编写一个视图