Django rest framework m2m post
I am getting an error when posting to one of my endpoints. Error text:
"<Customer: person@example.com>"
must have a value for the field"customer"
before the many-to-many relationship is used.
The client model is configured to be related to the m2m address model, with the addition of empty / null / default = None to make it optional.
If in the serializer I comment out the billing address field, my message succeeds and a new client is created.
I tried several payloads, where I quote the billing address how null
, []
and ""
to no avail.
Models
class Customer(TimeStamped):
# required
email = models.EmailField(max_length=255, unique=True)
has_agreed_to_terms = models.BooleanField(default=False)
## extras
# system id
user = models.OneToOneField('vauth.User', related_name='customer', blank=True, null=True, default=None)
# email preferences
subscription_type = models.CharField(max_length=255, blank=True, null=True, default=None)
unsubscribed_date = models.DateTimeField(blank=True, null=True, default=None)
email_frequency = models.CharField(max_length=255, null=True, blank=True, default='Weekly')
# addresses
billing_addresses = models.ManyToManyField('common.Address', related_name='billing_addresses_set', blank=True, null=True, default=None)
shipping_addresses = models.ManyToManyField('common.Address', related_name='shipping_addresses_set', blank=True, null=True, default=None)
# time stamps
date_joined = models.DateTimeField(default=timezone.now, db_index=True)
first_purchase_date = models.DateTimeField(blank=True, null=True, default=None, db_index=True)
last_purchase_date = models.DateTimeField(blank=True, null=True, default=None, db_index=True)
# purchases
number_of_purchases = models.IntegerField(default=0)
# braintree
braintree_id = models.CharField(max_length=255, blank=True, null=True, default=None)
serializers
class CustomerSerializer(serializers.HyperlinkedModelSerializer):
user = serializers.HyperlinkedRelatedField(view_name='user-detail', required=False)
billing_addresses = serializers.HyperlinkedRelatedField(many=True, view_name='address-detail', required=False)
# shipping_addresses = serializers.HyperlinkedRelatedField(many=True, view_name='address-detail', required=False)
class Meta:
model = Customer
fields = (
'url', 'id', 'email', 'has_agreed_to_terms', 'user', 'billing_addresses', #'shipping_addresses',
'subscription_type', 'unsubscribed_date', 'email_frequency',
'date_joined', 'first_purchase_date', 'last_purchase_date', 'number_of_purchases', 'braintree_id',
)
source to share
Since the version number was never given, I'm going to assume that this issue was happening in the DRF version before they established the order they created for the many-to-many relationship.
In Django REST Framework 3, you will not see this issue as DRF no longer automatically handles related fields. You should implement the creation and persistence of linked objects, which allows you to fix such problems by creating linked fields before creating the main one, and not vice versa, which causes this problem.
In Django REST Framework 2 , version 2.3 or otherwise, the order of object creation has been improved so that many-to-many objects are related after the main object is created.
source to share