【发布时间】:2016-11-30 03:17:47
【问题描述】:
我正在用 rest-framework-mongoengine 编写一个 django-rest-framework 后端。到目前为止,我有 2 种类型的模式 - 用户和设备(框)。来源如下:
models.py:
from __future__ import unicode_literals
import datetime
from mongoengine import Document, connect, EmbeddedDocument, fields, DynamicDocument
from django.db import models
# Create your models here.
from mongoengine import signals
connect('yourdb', alias='default')
class GPS(EmbeddedDocument):
lat = fields.FloatField(null=False, required=True)
lon = fields.FloatField(null=False, required=True)
class PPM(EmbeddedDocument):
time = fields.DateTimeField(default=datetime.datetime.now())
value = fields.IntField(null=False, required=True)
@classmethod
def pre_save(cls, sender, document, **kwargs):
document.time = datetime.datetime.now()
signals.pre_save.connect(PPM.pre_save, sender=PPM)
class BuyHistory(EmbeddedDocument):
time = fields.DateTimeField(default=datetime.datetime.now())
boxid = fields.StringField(max_length=128, null=False, required=True)
username = fields.StringField(max_length=128, null=False, required=True)
product = fields.StringField(max_length=128, null=False, required=True)
amount = fields.IntField()
@classmethod
def pre_save(cls, sender, document, **kwargs):
document.time = datetime.datetime.now()
signals.pre_save.connect(BuyHistory.pre_save, sender=BuyHistory)
class RecycleHistory(EmbeddedDocument):
time = fields.DateTimeField(default=datetime.datetime.now())
boxid = fields.StringField(max_length=128, null=False, required=True)
username = fields.StringField(max_length=128, null=False, required=True)
amount = fields.IntField()
@classmethod
def pre_save(cls, sender, document, **kwargs):
document.time = datetime.datetime.now()
signals.pre_save.connect(RecycleHistory.pre_save, sender=RecycleHistory)
class Box(Document):
boxid = fields.StringField(max_length=128, null=False, required=True)
gps = fields.EmbeddedDocumentField(GPS, required=True)
buy_history = fields.EmbeddedDocumentListField(BuyHistory, default='[]')
recycle_history = fields.EmbeddedDocumentListField(RecycleHistory, default='[]')
ppm_history = fields.EmbeddedDocumentListField(PPM, default='[]')
class User(Document):
username = fields.StringField(max_length=128, null=False, required=True)
rfid = fields.StringField(max_length=32, null=False, required=True)
buy_history = fields.EmbeddedDocumentListField(BuyHistory)
recycle_history = fields.EmbeddedDocumentListField(RecycleHistory)
serializers.py:
from rest_framework_mongoengine import serializers
from models import User, BuyHistory, Box, RecycleHistory, PPM
class UserSerializer(serializers.DocumentSerializer):
class Meta:
model = User
fields = ('username', 'rfid', 'buy_history', 'recycle_history')
class PPMSerializer(serializers.DocumentSerializer):
class Meta:
model = PPM
fields = ('time', 'value')
class BuyHistorySerializer(serializers.EmbeddedDocumentSerializer):
class Meta:
model = BuyHistory
fields = ('time', 'boxid', 'username', 'product', 'amount')
class RecycleHistorySerializer(serializers.EmbeddedDocumentSerializer):
class Meta:
model = RecycleHistory
fields = ('time', 'boxid', 'username', 'product', 'amount')
class BoxSerializer(serializers.DocumentSerializer):
class Meta:
model = Box
fields = ('id', 'boxid', 'gps', 'buy_history', 'recycle_history', 'ppm_history')
def update(self, instance, validated_data):
buy = validated_data.pop('buy_history')
recycle = validated_data.pop('recycle_history')
ppm = validated_data.pop('ppm_history')
updated_instance = super(BoxSerializer, self).update(instance, validated_data)
for buy_data in buy:
updated_instance.buy_history.append(BuyHistory(**buy_data))
for recycle_data in recycle:
updated_instance.recycle_history.append(RecycleHistory(**recycle_data))
for ppm_data in ppm:
updated_instance.ppm_history.append(PPM(**ppm_data))
updated_instance.save()
return updated_instance
我的目标是在更新Box 对象时更新用户的buy_history 和recycle_history。我该怎么做?
【问题讨论】:
-
数据库在哪里出现??
-
尝试将标题更改为更合适的内容
-
Kostya,您不应该为
EmbeddedDocuments手动创建EmbeddedDocumentSerializers,例如RecycleHistory、BuyHistory等 - 顶级DocumentSerializer会自动生成它们。我不确定pre_save信号是否适用于EmbeddedDocuments,因为您在顶级文档上调用save(),而不是它们的嵌入式子json。 -
@Bob 谢谢,我已经注释掉了
EmbeddedDocuments的序列化程序,它工作得很好。我只是按照这个手册。对于pre-save信号 - 它或多或少有效,但是后续更新的时间戳很奇怪 - 它们之间的差异以微秒为单位,但一般时间戳是正确的。 -
@ConstantineSamoilenko 序列化器工作得很好。不幸的是,我玩信号的时间还不够长,无法理解为什么时间戳会与现实不同,但感谢您的通知。
标签: python django django-rest-framework mongoengine restframeworkmongoengine