【发布时间】:2018-04-25 09:19:08
【问题描述】:
我有模型 Run。它表示数据的时间段度量:
class Run(models.Model):
start_time = models.DateTimeField(db_index=True)
end_time = models.DateTimeField()
chamber = models.ForeignKey(Chamber, on_delete=models.CASCADE)
class Meta:
unique_together=(('start_time', 'chamber'),)
以下是此端点的 POST 请求数据简介示例:
{
"start_time": "2018-11-11T12:00:00Z",
"end_time": "2018-11-11T12:00:01Z",
"chamber": "My Test Chamber"
}
一个Run属于一个Chamber并且有一个start_time和end_time
Run 不能共享相同的 Chamber 和 start_time。如果我的请求数据简介中的 start_time 和 Chamber 相同,则表示 Run 仍在进行中,需要更新。 p>
当请求第一次通过时,我创建了一个 Run 对象,它工作正常。发送请求的传感器随后将发送相同的 POST 请求数据简介,只要“运行”正在进行,仅更改数据简介的 end_time。
传感器不发送 PUT 或 PATCH,它只发送 POST,这可能是一个问题,但它无法修复,所以我不得不处理 POST 请求。
我想要的行为是:
- 第一次发送 Run 数据简介时,创建一个新的 Run 对象
- 只要我在数据简介中收到相同的 Chamber 和 run_start,(检查该组合是否存在),更新 Run的end_time(运行正在进行中)
这里是序列化器:
class RunsCreateSerializer(ModelSerializer):
class Meta:
model = Run
fields = [
'id',
'chamber',
'start_time',
'end_time'
]
这里是 API 端点上的 views.py:
class RunsCreateAPIView(CreateAPIView):
queryset = Run.objects.all()
queryset = queryset.prefetch_related('chamber')
serializer_class = RunsCreateSerializer
permission_classes = [IsAuthenticated]
def create(self, request, *args, **kwargs):
try:
chamber = Chamber.objects.get(chamber_name=request.data["chamber"])
request.data["chamber"] = chamber.id
except:
print("Invalid chamber name")
serializer = RunsCreateSerializer(data=request.data)
print(serializer)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
return Response(serializer.errors)
现在,我发现我必须稍微修改 views.py 上的“create”,因为传感器将 Chamber 作为字符串标识符发送。然后,我必须对照我的 Chamber 表检查该字符串并检索对象实例,然后修改请求数据以用 Chamber 字符串替换它在我的数据库中的 ID。我不确定这是否是正确的方法,但它对我有用。
现在我尝试解决这个问题:
在 serializers.py 上:
def create(self, validated_data):
run, created = Run.objects.update_or_create(
chamber=validated_data.get('chamber'),
start_time=validated_data.get('start_time'),
end_time=validated_data.get('end_time'))
return run
def update(self, run, validated_data):
run.chamber = validated_data.get('chamber', run.chamber)
run.start_time = validated_data.get('start_time', run.start_time)
run.created = validated_data.get('created', run.created)
run.save()
return run
我认为通过在我的序列化程序上执行此操作,我将能够更新对象,但它似乎没有达到这一点(尝试在创建和更新方法上使用 print("Sanity check"),我看不到我的健全性检查输出,所以我知道我没有达到那个点)。
我怀疑这与我在视图上覆盖 create 方法有关,但我不确定。
如果您知道如何更新对象,并且可能让序列化程序/视图处理 Chamber 名称的字符串,而不必干预用于替换 ID 字符串的方法,我将不胜感激帮助。
【问题讨论】:
-
查看我对另一个线程的回答:stackoverflow.com/a/59756993/7392069
标签: python django django-rest-framework django-serializer