我正在使用Django 2.0
和Django REST Framework
编写REST API。
我的 contacts / models.py 包含
class Contact(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100, blank=True, null=True)
date_of_birth = models.DateField(blank=True, null=True)
avatar = models.ImageField(upload_to='contact/%Y/%m/%d', blank=True)
class Meta:
db_table = 'contacts'
class ContactPhoneNumber(models.Model):
contact = models.ForeignKey(Contact, on_delete=models.CASCADE)
phone = models.CharField(max_length=100)
class Meta:
db_table = 'contact_phone_numbers'
和 contacts / serializers.py
class ContactPhoneNumberSerializer(serializers.ModelSerializer):
class Meta:
model = ContactPhoneNumber
fields = ('id', 'phone', 'primary', 'created', 'modified')
class ContactSerializer(serializers.HyperlinkedModelSerializer):
phone_numbers = ContactPhoneNumberSerializer(source='contactphonenumber_set', many=True)
url = serializers.HyperlinkedRelatedField(
view_name='contacts:detail',
read_only=True
)
class Meta:
model = Contact
fields = ('url', 'id', 'first_name', 'last_name', 'date_of_birth', 'avatar', 'phone_numbers')
def create(self, validated_data):
print(validated_data)
instance = Contact.objects.create(**validated_data)
instance.save()
return instance
我希望能够与contact
一起创建phone_number
,并且一个联系人可以拥有多个电话号码。
但是当我发送只有联系人数据的POST请求时,它会出错
'contactphonenumber_set' is an invalid keyword argument for this function
仅在呼叫联系人时显示json响应中的所有关联手机号码,但无法创建记录。
print(validated_data)
提供以下数据
{'first_name': 'Anshuman', 'last_name': 'Upadhyay', 'date_of_birth': datetime.date(2018, 5, 15), 'contactphonenumber_set': [], 'user_id': <SimpleLazyObject: <User: anuj>>}
如何使用REST Framework创建相关的多个字段?
答案 0 :(得分:3)
您无法直接将contactphonenumber_set
传递给objects.create()
方法。您应该分别创建每个相关的语音,如下所示:
def create(self, validated_data):
print(validated_data)
phone_numbers = validated_data.pop('contactphonenumber_set')
instance = Contact.objects.create(**validated_data)
for phone_data in phone_numbers:
ContactPhoneNumber.objects.create(contact=instance, **phone_data)
return instance
查看有关可写嵌套序列化程序here的详细信息。
答案 1 :(得分:0)
models.py:
class UnitGroup(models.Model):
name = models.CharField(max_length=255,
verbose_name='名称')
class Unit(models.Model):
unit_group = models.ForeignKey('medicine.UnitGroup',
related_name='unit_unit_group',
null=True,
on_delete=models.SET_NULL,
verbose_name='unit_group')
name = models.CharField(max_length=255,
verbose_name='name')
display_name = models.CharField(max_length=255,
verbose_name='display_name')
serializers.py:
class UnitCreateSerializer(ModelSerializer):
class Meta:
model = Unit
fields = ('name', 'display_name', 'ratio', 'is_active')
class UnitGroupCreateSerializer(WritableNestedModelSerializer):
unit_unit_group = UnitCreateSerializer(many=True)
class Meta:
model = UnitGroup
fields = ('unit_unit_group', 'name')
tests.py:
class UnitGroupTests(APITestCase):
def setUp(self):
try:
self.user = User.objects.get(tel='18094213198')
except User.DoesNotExist:
self.user = User.objects.create_user(tel='18094213198', password='123456')
self.user.user_permissions.add(*get_model_permission(UnitGroup))
token, _ = Token.objects.get_or_create(user=self.user)
self.access_token = token.access_token
def test_create(self):
"""create"""
url = reverse('unitgroup-list')
self.client.credentials(HTTP_AUTHORIZATION='Token ' + self.access_token)
data = {'name': 'Widget', 'unit_unit_group': [{'name': '1', 'display_name': 'yi'}]}
response = self.client.post(url, data, format='json')
print([(x, x.unit_group) for x in Unit.objects.all()])
print('create', json.dumps(response.data, ensure_ascii=False, indent=2))
self.assertEqual(response.status_code, status.HTTP_200_OK)
测试输出:
[(<Unit: 1>, <UnitGroup: Widget>)]
create{
"id": 1,
"name": "Widget",
"create_time": "2018-05-08 16:59:51",
"update_time": "2018-05-08 16:59:51"
}