Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
django-tastypie:使用中间模型获取m2m关系的额外值_Django_Many To Many_Tastypie_M2m - Fatal编程技术网

django-tastypie:使用中间模型获取m2m关系的额外值

django-tastypie:使用中间模型获取m2m关系的额外值,django,many-to-many,tastypie,m2m,Django,Many To Many,Tastypie,M2m,我正在尝试将tastype与许多关系一起使用中间模型(通过关键字)() 我正在使用这些模型: class Point(models.Model): ... value = models.FloatField(_('Value'), null=True) rooms = models.ManyToManyField('rooms.Room', through='points.PointPosition') class Room(models.Model): tit

我正在尝试将tastype与许多关系一起使用中间模型(通过关键字)()

我正在使用这些模型:

class Point(models.Model):
    ...
    value = models.FloatField(_('Value'), null=True)
    rooms = models.ManyToManyField('rooms.Room', through='points.PointPosition')

class Room(models.Model):
    title = models.CharField(max_length=64)

class PointPosition(models.Model):
    point = models.ForeignKey('points.Point', verbose_name=_('Point'))
    room = models.ForeignKey('rooms.Room', verbose_name=_('Room'))
    x = models.IntegerField(_('Y'))
    y = models.IntegerField(_('X'))
我已经能够获取多对多关系,但是无法获取额外字段。这是我的tastypie代码:

class PointResource(ModelResource):
    class Meta:
        queryset = Point.objects.select_related(
            depth=10
            ).prefetch_related('rooms').all()
        resource_name = 'point'
        allowed_methods = ['get']

    ...
    value = fields.FloatField()
    rooms = fields.ToManyField('rooms.api.RoomResource', 'rooms', full=True)

class RoomResource(ModelResource):
    class Meta:
        queryset = Room.objects.all()
        resource_name = 'room'
        allowed_methods = ['get']
我一直在尝试使用一种方法对我的PointResource中的room变量进行水合物化处理,如下所示:

def dehydrate_rooms(self, bundle):                                                                                                                                                                                                                          
    rooms = []                                                                                                                                                                                                                                              
    for room in bundle.obj.rooms.all():                                                                                                                                                                                                                     
        position = PointPosition.objects.get(                                                                                                                                                                                                               
            room_id = room.pk,                                                                                                                                                                                                                              
            point_id = bundle.obj.pk)                                                                                                                                                                                                                                               
        rooms.append({'id': room.pk,                                                                                                                                                                                                                                 
             'title': room.title,                                                                                                                                                                                                                           
             'x': position.x,                                                                                                                                                                                                                               
             'y': position.y})                                                                                                                                                                                                                                               
    return rooms 
但问题是,它会创建尽可能多的查询:当你有+8000点时,它是一个真正的性能杀手

我没有找到任何有用的资源来提高性能。 我曾考虑使用QuerySet可用的.extra()方法进行自定义查询,但JOIN关键字不可用(该补丁在几个月前被拒绝)。
我不确定SELECT子查询是否会起作用。

您是否考虑过将查询集更改为使用
PointPosition
资源?从听起来,“点”在数据库中的含义实际上与API中“点”的含义不同,因此需要进行一些转换以隐藏内部细节:

class PointResource(ModelResource):
    class Meta:
        queryset = PointPosition.objects.select_related("point", "room")
        resource_name = 'point'
        allowed_methods = ('get', )

以需要调整过滤参数为代价,这将避免执行多个查询。您的
脱水
方法可以根据需要交换数据。通过使用
.values()
仅将必要的字段作为字典而不是完整对象拉出,您还可以节省一些开销。

非常感谢您的回答。事实上,我就是这么做的,但我没有想到用
脱水
交换元素来重新排列我的字典。酷提示:)我花了太多时间和Tastype打交道,然后才提醒自己,它只是构建一个简单的数据结构,没有一种正确的方法来构建字典。我至少有一个资源,其中一个被严重重写的ModelResource变成了一个简单的资源,它直接调用ORM来高效地构建复杂的数据结构。