Reputation: 497
I want to create two entries from one post request. One in the 'Dates' model and one in 'Other' model. Code corresponding to both models is shown below.
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'
Other is:
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'
I have validated the data from Dates Serializer and created the object in 'Dates' table. Now, I want to use the generated 'booking_id' as the same 'booking_id' for 'Other' table. How can I validate serializer and create an object in the 'Other' table while maintaining the consistency? Here with consistency, I mean: Either create objects in both the tables if no error occurs or don't create an object if any error occurs.
Upvotes: 0
Views: 536
Reputation: 5482
You can make use of writable nested serializers to achieve this. You need to define a serializer class for Other model, then your Dates serializer can look like this:
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
You can use the defaul CreateModelMixin of DRF here, all nested object logic is handled in the serializer.
Upvotes: 2