django - Django 反向关系序列化器
问题描述
我正在尝试创建一个用于自学的项目,而现在,我被困在了这一点上。
它是一个活动策划者,每个活动都会有肉。活动的组织者可以为他的活动选择或创建新的肉类类型。活动创建后,客人可以从组织者挑选的选择池中选择他们喜欢的肉类。
例如,作为一个组织者,我可以说我会从一张MeatType
有“鸡肉”、“火鸡”和“猪肉”的桌子上吃“鸡肉”、“火鸡”和“牛肉”。(组织者将创建一个新的MeatType
并为他的活动选择它)
所以我有 3 个与这个特定问题相关的 Django 模型。
事件模型:
class Event(models.Model):
name = models.CharField(_('Event name'), max_length=255)
capacity = models.IntegerField(_('Capacity'), null=True)
address = models.CharField(_('Address'), max_length=255)
date = models.DateTimeField(_('Event Date'), db_index=True)
organizer = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name=_('Organizer'), related_name='events',
on_delete=models.CASCADE)
肉类型号:
class MeatType(models.Model):
"""
A model just to hold meat type names on the database.
This model will only have a "name" field which represents the Meat Type.
For example, "Chicken" or "Beef"
"""
name = models.CharField(_('Name'), max_length=255)
和可用的肉类型号:
class AvailableMeatType(models.Model):
"""
Available meat types for the event selected by Organizer
"""
event = models.ForeignKey(Event, verbose_name=_('Event'), related_name='available_meat_types',
on_delete=models.CASCADE)
meat_type = models.ForeignKey(MeatType, verbose_name=_('Meat Type'), on_delete=models.CASCADE)
根据这个结构,要创建一个事件,组织者应该发送一个如下所示的请求:
{
"name": "Team BBQ",
"capacity": 10,
"address": "Down Town",
"date": "2019-02-01T18:00",
"available_meat_type_ids": [
1,
2,
3
]
}
其中 1 , 2 和 3 是Meat Type
ID,但会创建Available Meat Type
如下对象: { 123, 1 } , { 123, 2} , { 123, 3} 其中 123 是创建的事件 ID
** 我的序列化器 **
class EventSerializer(serializers.ModelSerializer):
"""
A serializer class for creating and listing events
"""
organizer = serializers.PrimaryKeyRelatedField(read_only=True)
available_meat_type_ids = serializers.PrimaryKeyRelatedField(
many=True,
read_only=True
)
class Meta:
model = Event
fields = (
'id',
'name',
'capacity',
'address',
'date',
'organizer',
'available_meat_type_ids'
)
read_only_fields = ('organizer', )
def post(self, request, *args, **kwargs):
"""
Create available meat type object
"""
# I dont know what to do here
pass
@staticmethod
def validate_date(date):
# Date of the event can not be on the past
if date < timezone.now():
raise Exception("Date of the new event can not be on the past.")
return date
class CreateAvailableMeatTypeSerializer(serializers.ModelSerializer):
"""
A serializer for available meat type request.
"""
event = serializers.PrimaryKeyRelatedField(required=True, queryset=Event.objects)
meat_type = serializers.PrimaryKeyRelatedField(required=True, queryset=MeatType.objects)
class Meta:
model = AvailableMeatType
fields = (
'id',
)
我不知道如何使它工作。我试图在网上搜索,但找不到任何有用的东西。
如何根据在事件创建请求中收到的肉类类型 ID 创建可用的肉类类型对象?
解决方案
我认为您可以通过以下方式简单地做到这一点:
class EventSerializer(serializers.ModelSerializer):
organizer = serializers.PrimaryKeyRelatedField(read_only=True)
available_meat_type_ids = serializers.PrimaryKeyRelatedField(
many=True,
read_only=True
)
meat_id = serailizers.IntegerField()
class Meta:
model = Event
fields = (
'id',
'name',
'capacity',
'address',
'date',
'organizer',
'available_meat_types',
'meat_id'
)
read_only_fields = ('organizer', )
write_only_fields = ('meat_id',)
def create(self, validate_data):
meat_id = validate_data.pop('meat_id')
event = Event.objects.create(**validate_data)
AvailableMeatType.objects.create(event=event, meat_type_id=meat_id)
return event
有关更多详细信息,请查看 PrimaryKeyRelatedField 上的文档。
推荐阅读
- java - Accessing field in Java based on condition
- flutter - 如何在库比蒂诺日期选择器字段中显示初始日期
- javascript - Distributable/Distributed Web App with VueJS
- pandas - pandas-like resampling with week frequency in DolphinDB
- json - 如何访问 json / ruby 中的键、值
- powershell - Powershell:列出 ADusers - 需要用户所属的组
- exe - 执行 exe 文件时出错。“原因:系统找不到指定的文件”
- android - 我得到“调用需要 API 级别 X(当前最小值为 Y)”,即使我将 min 更改为 X
- web-scraping - 是否可以将 Scrapy 实现到桌面应用程序中?
- django - Heroku 在通过 Django 部署之前构建 React 应用程序