我正在用rest-framework-mongoengine编写一个django-rest-framework后端。到目前为止,我有2种类型的模式 - 用户和设备(Box)。资料来源如下:
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
我的目标是在更新buy_history
对象时更新用户的recycle_history
和Box
。我该怎么办?
答案 0 :(得分:0)
好的,我找到了一个解决方案,显然它非常简单,但如果有人有类似的困惑,那么答案就是:
只需使用user
username
获取嵌套对象中设置的for buy_data in buy:
buy_history_s = BuyHistory(**buy_data)
try:
user = User.objects.get(username=buy_history_s.username)
except errors.DoesNotExist:
raise exceptions.AuthenticationFailed()
if buy_history_s.time is None:
buy_history_s.time = datetime.datetime.now()
updated_instance.buy_history.append(buy_history_s)
user.buy_history.append(buy_history_s)
user.save()
。
public function category(){
return $this->belongsTo(Category::class);
}
干杯