【问题标题】:Create multiple model instances of interlinked models through one post request in DRF通过 DRF 中的一个 post 请求创建互连模型的多个模型实例
【发布时间】:2019-08-08 04:00:00
【问题描述】:

我想从一个帖子请求创建两个条目。一个在“日期”模型中,一个在“其他”模型中。两种模型对应的代码如下所示。

class Dates(models.Model):
  booking_id = models.AutoField(primary_key=True)
  timestamp = models.DateTimeField(auto_now_add=True)
  feedback = models.CharField(max_length=8, default='no')
  myself = models.BooleanField(default=True)

  class Meta:
    app_label = 'bookings'

其他是:

class Other(models.Model):
  booking_id = models.OneToOneField(
                'bookings.Dates',
                null=False,
                default=1,
                primary_key=True,
                on_delete=models.CASCADE
            )
  name = models.CharField(max_length=64)
  phone_number = models.CharField(max_length=14)
  email_id = models.EmailField(max_length=128)

  class Meta:
    app_label = 'bookings'

我已经验证了 Dates Serializer 中的数据并在“Dates”表中创建了对象。现在,我想将生成的“booking_id”用作“其他”表的“booking_id”。如何在保持一致性的同时验证序列化程序并在“其他”表中创建对象? 这里的一致性,我的意思是:如果没有发生错误,则在两个表中创建对象,或者如果发生任何错误,则不创建对象。

【问题讨论】:

标签: django post django-models django-rest-framework serialization


【解决方案1】:

您可以使用可写的嵌套序列化器来实现这一点。您需要为 Other 模型定义一个序列化器类,然后您的 Dates 序列化器可以如下所示:

class DatesSerializer(serializers.ModelSerializer):
    other = OtherSerializer()

    class Meta:
        model = Dates
        fields = ('timestamp', 'feedback', 'myself', 'other')

    def validate_other(self, value):
        # Run validations for Other model here, either manually or through OtherSerializer's is_valid method. You won't have booking_id in value here though, take that into account when modelling your validation process

    def validate_feedback(self, value):
        # Run validations specific to feedback field here, if necessary. You can do this for all serializer fields

    def validate(self, data):
        # Run non-field specific validations for Dates here

    def create(self, validated_data):
        # At this point, validation for both models are run and passed

        # Pop other model data from validated_data first
        other_data = validated_data.pop('other')

        # Create Dates instance 
        dates = Dates.objects.create(**validated_data)

        # Create Other instance now
        Other.objects.create(booking_id=dates, **other_data)

        return dates

这里可以使用DRF默认的CreateModelMixin,所有嵌套对象逻辑都在序列化器中处理。

【讨论】:

  • 你能告诉我,OtherSerializer() 会包含所有字段还是除 booking_id 之外的所有字段?
  • 在这个setp中,除了booking_id之外的所有字段
  • 我还没有编写用于验证其他 (validate_other) 的代码,但它仍在工作。以后会不会出问题?
  • 一个可能的问题是,如果缺少其他请求中提供的数据,您最终可能会创建一个 Dates 实例但没有关联的 Other 实例,因为 Other.objects.create(booking_id=dates, **other_data) 会失败。另一个可能的问题是您可能会在其他情况下得到无效数据(例如无效的电话号码)
猜你喜欢
  • 1970-01-01
  • 2017-06-03
  • 2023-03-23
  • 1970-01-01
  • 2020-09-13
  • 2020-07-26
  • 2021-01-05
  • 1970-01-01
  • 2015-08-01
相关资源
最近更新 更多