我已经花了几天时间阅读这些房子(我有几次rtfm ......或许我还没有理解tfm)。接近几个答案,我担心最终我知道Django / Serilizers(原文如此)是如何工作的。
我将从我的基本问题开始,以保持简单,而不是我为使这项工作所做的众多尝试。
我正在尝试执行以下操作:
如上所述,GET声明正在发挥作用。该视图基于transactionID列表和URL中传递的control_sys(sysID)检索查询集。它将此传递给序列化器并通过API返回数据。
更新(PUT)无效。我的问题似乎是我没有将模型的pk(id字段)传递给API,并且它在发布到API的数据中不可用。我需要以与GET语句相同的方式检索查询集并将其传递给更新,此时当我尝试验证seriliser时,我收到以下错误:
AttributeError:' QuerySet'对象没有属性' pk'
Django Rest Framework Validator Code
第155行的验证者正在提出这个问题我很困惑,因为我已经检查过,并且查询集中的每个项都有一个值id(当我引用pk时返回)。我也尝试更新视图中的数据以附加pk / id值无效。
我正在通过' many = True'以便seriliser知道它是一个接收的查询集而不是单个模型实例。
到目前为止,我尝试过:
我知道验证失败但我不知道如何解决这个问题。
非常欢迎任何建议。
下面有一些参考信息......我会根据要求发布更多信息。
型号:
## Comms Queue
class CommsQueue(models.Model):
# primary key
# foreign key
control_sys = models.IntegerField("Control system foreign key (passive)", blank=True, null=True, default=None)
meter = models.IntegerField("Meter foreign key (passive)", blank=True, null=True, default=None)
# string
data = models.CharField("Comm data", max_length=200, blank=True, null=True, default=None)
# int
transactionID = models.BigIntegerField("Comms Transaction ID", blank=True, null=False)
source = models.IntegerField("Originating source for event", blank=True, null=False)
target = models.IntegerField("Target destination for event", blank=True, null=False, db_index=True)
priority = models.IntegerField("Comms priority", blank=True, default=0)
# url
URI = models.URLField("Comm URI",max_length=200, blank=True, null=True, default=None)
# bool
#comm_send = models.BooleanField("Event requires uplink/downlink", blank=False, default=True) # TODO delete?
comm_sent = models.BooleanField("Uplink/Downlink sent", blank=True, default=False)
complete_req = models.BooleanField("Require completion notice", blank=True, default=False)
complete = models.BooleanField("Event complete", blank=True, default=False)
# date
create_date = models.DateTimeField("Date created", auto_now=False, auto_now_add=True)
last_date = models.DateTimeField("Date accessed", auto_now=True, auto_now_add=False)
class Meta:
unique_together = (("control_sys","transactionID"),)
index_together = [("control_sys","transactionID"),]
def __unicode__(self):
return "Transaction ID: %s, Complete: %s" % (str(self.transactionID), str(self.complete))
Serilizer :
class CommsSerialiser(serializers.HyperlinkedModelSerializer):
URI = ParameterisedHyperlinkedIdentityField(view_name="comms-detail", lookup_fields=(('control_sys', 'sysID'), ('transactionID', 'tID')), read_only=True)
# convert MySQL bool to int bool
complete_req = serializers.IntegerField(read_only=False)
complete = serializers.IntegerField(read_only=False)
class Meta:
model = CommsQueue
fields = ('control_sys', 'meter', 'data', 'transactionID', 'source', 'target', 'priority', 'complete_req', 'complete', 'URI')
validators = [
UniqueTogetherValidator(
queryset=CommsQueue.objects.all(),
fields=('control_sys', 'transactionID')
)
]
查看:
class CommsDetail(APIView):
"""
Retrieve, update or delete MULTIPLE comms from queue.
"""
# session permissions
permission_classes = (permissions.IsAuthenticated, IsAuthedCommQueue,)
def get_object(self, sysID, transactionID_list):
try:
# get comms queue for control unit ...allow retrieve of complete comms
comm_objects = CommsQueue.objects.filter(control_sys=sysID,transactionID__in=transactionID_list)
# Auth user for control unit
self.check_object_permissions(self.request, comm_objects[0])
# get object
return comm_objects
except ObjectDoesNotExist:
raise Http404
def get(self, request, sysID, format=None):
# build list of transaction ID to retrieve
transactionID_list = []
for transaction in request.data:
transactionID_list.append(transaction['transactionID'])
comms = self.get_object(sysID,transactionID_list)
serializer = CommsSerialiser(comms, context={'request': request}, many=True)
return Response(serializer.data)
def put(self, request, sysID, format=None):
# build list of transaction ID to retrieve
transactionID_list = []
for transaction in request.data:
transactionID_list.append(transaction['transactionID'])
print transaction
comms = self.get_object(sysID,transactionID_list)
serializer = CommsSerialiser(comms, data=request.data, context={'request': request}, many=True)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
' print serilizer'输出:
CommsSerialiser(<QuerySet[
<CommsQueue: TransactionID: 313011,
Complete: False>,
<CommsQueue: TransactionID: 313013,
Complete: False>,
<CommsQueue: TransactionID: 313102,
Complete: False>
]>,
context={
u'request': <rest_framework.request.Requestobject>
},
data=[
{
u'control_sys': 710017,
u'complete': 1,
u'data': u'"{data innit}"',
u'URI': u'http: //172.16.32.40: 8000/api/0.1/comm/710017/313102/',
u'transactionID': 313102,
u'complete_req': 1
},
{
u'control_sys': 710017,
u'complete': 1,
u'data': u'"{data innit}"',
u'URI': u'http: //172.16.32.40: 8000/api/0.1/comm/710017/313011/',
u'transactionID': 313011,
u'complete_req': 1
},
{
u'control_sys': 710017,
u'complete': 1,
u'data': u'"{data arg}"',
u'URI': u'http: //172.16.32.40: 8000/api/0.1/comm/710017/313013/',
u'transactionID': 313013,
u'complete_req': 1
}
],
many=True):
control_sys = IntegerField(allow_null=True, label='Control system foreign key (passive)', max_value=2147483647, min_value=-2147483648, required=False)
meter = IntegerField(allow_null=True, label='Meter foreign key (passive)', max_value=2147483647, min_value=-2147483648, required=False)
data = CharField(allow_blank=True, allow_null=True, label='Comm data', max_length=200, required=False)
transactionID = IntegerField(label='Comms Transaction ID', max_value=9223372036854775807, min_value=-9223372036854775808, required=False)
source = IntegerField(label='Originating source for event', max_value=2147483647, min_value=-2147483648, required=False)
target = IntegerField(label='Target destination for event', max_value=2147483647, min_value=-2147483648, required=False)
priority = IntegerField(label='Comms priority', max_value=2147483647, min_value=-2147483648, required=False)
complete_req = IntegerField(read_only=False)
complete = IntegerField(read_only=False)
URI = ParameterisedHyperlinkedIdentityField(lookup_fields=(('control_sys', 'sysID'), ('transactionID', 'tID')), read_only=True, view_name='comms-detail')