Я использую Django 2.0 и Python 3.7. У меня есть следующие модели (CoopType - это поле «многие ко многим» Coop) ...
class CoopTypeManager(models.Manager):
def get_by_natural_key(self, name):
return self.get_or_create(name=name)[0]
class CoopType(models.Model):
name = models.CharField(max_length=200, null=False)
objects = CoopTypeManager()
class Meta:
unique_together = ("name",)
class CoopManager(models.Manager):
# Look up by coop type
def get_by_type(self, type):
qset = Coop.objects.filter(type__name=type,
enabled=True)
return qset
# Look up coops by a partial name (case insensitive)
def find_by_name(self, partial_name):
queryset = Coop.objects.filter(name__icontains=partial_name, enabled=True)
print(queryset.query)
return queryset
# Meant to look up coops case-insensitively by part of a type
def contains_type(self, types_arr):
filter = Q(
*[('type__name__icontains', type) for type in types_arr],
_connector=Q.OR
)
queryset = Coop.objects.filter(filter,
enabled=True)
return queryset
class Coop(models.Model):
objects = CoopManager()
name = models.CharField(max_length=250, null=False)
types = models.ManyToManyField(CoopType)
#type = models.ForeignKey(CoopType, on_delete=None)
address = AddressField(on_delete=models.CASCADE)
enabled = models.BooleanField(default=True, null=False)
phone = PhoneNumberField(null=True)
email = models.EmailField(null=True)
web_site = models.TextField()
Я не знаю, как правильно создать сериализатор для приема входных данных , У меня есть эти сериализаторы ...
class CoopTypeField(serializers.PrimaryKeyRelatedField):
queryset = CoopType.objects
def to_internal_value(self, data):
if type(data) == dict:
cooptype, created = CoopType.objects.get_or_create(**data)
# Replace the dict with the ID of the newly obtained object
data = cooptype.pk
return super().to_internal_value(data)
...
class CoopSerializer(serializers.ModelSerializer):
type = CoopTypeField()
address = AddressTypeField()
class Meta:
model = Coop
fields = ['id', 'name', 'types', 'address', 'phone', 'enabled', 'email', 'web_site']
extra_kwargs = {
'phone': {
'required': False,
'allow_blank': True
}
}
def to_representation(self, instance):
rep = super().to_representation(instance)
rep['type'] = CoopTypeSerializer(instance.type).data
rep['address'] = AddressSerializer(instance.address).data
return rep
def create(self, validated_data):
"""
Create and return a new `Snippet` instance, given the validated data.
"""
CoopSerializer.update_coords(validated_data)
return Coop.objects.create(**validated_data)
Однако, это приводит к следующей ошибке
AssertionError: The field 'type' was declared on serializer CoopSerializer, but has not been included in the 'fields' option.
, когда я отправляю запрос (JSON ниже). Как лучше настроить мои сериализаторы?
{
"name": "6899",
"types": [
{"name": "Coworking Space"},
{"name": "Library"}
],
"address": {
"formatted": "222 W. Merchandise Mart Plaza, Suite 1212",
"locality": {
"name": "Chicago",
"postal_code": "60654",
"state": 19313
}
},
"enabled": true,
"phone": "312473",
"email": "laredotornado@msn.com",
"web_site": "http://www.1871.com/"
}