相关疑难解决方法(0)

TypeError:'RelatedManager'对象不可迭代

Django的

我有下一个型号:

class Group(models.Model):
    name = models.CharField(max_length=100)
    parent_group = models.ManyToManyField("self", blank=True)

    def __unicode__(self):
        return self.name


class Block(models.Model):

    name = models.CharField(max_length=100)
    app = models.CharField(max_length=100)
    group = models.ForeignKey(Group)

    def __unicode__(self):
        return self.name
Run Code Online (Sandbox Code Playgroud)

比方说,块b1g1组.根据它的名字,我想从g1组中获取所有块.我写了下一个递归函数:

def get_blocks(group):

    def get_needed_blocks(group):
        for block in group.block_set:
            blocks.append(block)

        if group.parent_group is not None:
            get_needed_blocks(group.parent_group)

    blocks = []
    get_needed_blocks(group)
    return blocks
Run Code Online (Sandbox Code Playgroud)

但是b1.group.block_set返回我的RelatedManager对象,它不可迭代.

该怎么办?怎么了?

python django django-models django-queryset

67
推荐指数
3
解决办法
4万
查看次数

ModelSerializer在Django REST框架中非常慢

我正在为我的API使用Django REST框架,昨天我想看看它如何适用于大数据.我找到了关于如何描述你的请求的教程(由Tom Christie编写),我发现对于10,000个用户,我的请求花费了惊人的2:20分钟.

大部分时间花在序列化对象上(大约65%),所以我想知道我该怎样做才能加快速度?

我的用户模型实际上扩展了默认的django模型,因此使用.values()不起作用,因为我也没有得到嵌套模型(即使它更快了).

任何帮助将不胜感激 :)

编辑

我在检索我的查询集时已经在使用.select_related(),它已经改善了我的时间,但只有几秒钟.总查询数是10,所以我的问题不在于数据库访问.

另外,我使用.defer(),以避免在此请求中不需要的字段.这也提供了一个小的改进,但还不够.

编辑#2

Models

from django.contrib.auth.models import User
from django.db.models import OneToOneField
from django.db.models import ForeignKey

from userena.models import UserenaLanguageBaseProfile
from django_extensions.db.fields import CreationDateTimeField
from django_extensions.db.fields import ModificationDateTimeField

from mycompany.models import MyCompany


class UserProfile(UserenaLanguageBaseProfile):
    user = OneToOneField(User, related_name='user_profile')
    company = ForeignKey(MyCompany)
    created = CreationDateTimeField(_('created'))
    modified = ModificationDateTimeField(_('modified'))
Run Code Online (Sandbox Code Playgroud)

Serializers

from django.contrib.auth.models import User

from rest_framework import serializers

from accounts.models import UserProfile


class UserSerializer(serializers.ModelSerializer):
    last_login = serializers.ReadOnlyField()
    date_joined = serializers.ReadOnlyField() …
Run Code Online (Sandbox Code Playgroud)

django django-orm django-rest-framework

9
推荐指数
3
解决办法
7138
查看次数

Django REST Framework Serialize非常慢

我在Python 2.7和Django 1.7.1与django-restframework我有一个API,它返回我从数据库采取的一些特定值,它使用这样的自定义序列化器:

class InventarioSerializer(serializers.ModelSerializer):
    item = serializers.RelatedField(source='producto.item')
    ubicacion = serializers.RelatedField(source='ubicacion.nombre')
    class Meta:
        model = Inventario
        fields = ('epc','item','cantidad','ubicacion')
Run Code Online (Sandbox Code Playgroud)

我的API视图以这种方式调用:

class ItemEnInventarioViewSet(InventarioListModelMixin, viewsets.ModelViewSet):
    serializer_class = InventarioSerializer
    renderer_classes = (UnicodeJSONRenderer,)
Run Code Online (Sandbox Code Playgroud)

我的ListModelMixin是这样的:

class InventarioListModelMixin(object):
    def list(self, request, *args, **kwargs):
        item = request.QUERY_PARAMS.get('item', None)
        inventario = Inventario.objects.filter(producto__item = item)
        if inventario.count() == 0:
            return HttpResponse(u"El item %s no se encuentra en el inventario" % item,status=400)
        self.object_list = inventario
        # Switch between paginated or standard style responses
        page = self.paginate_queryset(self.object_list)
        if page is not …
Run Code Online (Sandbox Code Playgroud)

django serialization json django-queryset django-rest-framework

8
推荐指数
2
解决办法
8665
查看次数

Django MPTT 使用 DRF 高效序列化关系数据

我有一个 MPTT 模型的类别模型。它是 m2m 到 Group,我需要用相关计数序列化树,想象我的类别树是这样的:

Root (related to 1 group)
 - Branch (related to 2 groups) 
    - Leaf (related to 3 groups)
...
Run Code Online (Sandbox Code Playgroud)

所以序列化的输出看起来像这样:

{ 
    id: 1, 
    name: 'root1', 
    full_name: 'root1',
    group_count: 6,
    children: [
    {
        id: 2,
        name: 'branch1',
        full_name: 'root1 - branch1',
        group_count: 5,
        children: [
        {
            id: 3,
            name: 'leaf1',
            full_name: 'root1 - branch1 - leaf1',
            group_count: 3,
            children: []
        }]
    }]
}
Run Code Online (Sandbox Code Playgroud)

这是我目前的超级低效实现:

模型

class Category(MPTTModel):
    name = ...
    parent = ... (related_name='children')

    def get_full_name(self): …
Run Code Online (Sandbox Code Playgroud)

python django serialization django-mptt django-rest-framework

7
推荐指数
1
解决办法
4367
查看次数

Django在一次调用中序列化多个对象

我想知道如何在序列化时减少对数据库的调用次数:

我有以下两种型号:

 class House(models.Model):
     name = models.CharField(max_length = 100, null = True, blank = True)
     address = models.CharField(max_length = 500, null = True, blank = True)

 class Room(models.Model):
      house = models.ForeignKey(House)
      name  = models.CharField(max_length = 100)
Run Code Online (Sandbox Code Playgroud)

有1个房子,它可以有多个房间.

我正在使用django-rest-framework并尝试在房屋级别将所有3个事物序列化.

 class HouseSerializer(serializers.ModelSerializer)
    rooms = serializers.SerializerMethodField('room_serializer')

    def room_serializer(self):
         rooms = Room.objects.filter(house_id = self.id) # we are in House serializer, so self is a house
         return RoomSerializer(rooms).data

    class Meta:
        model = House
        fields = ('id', 'name', 'address')
Run Code Online (Sandbox Code Playgroud)

所以现在,对于我想要序列化的每个房子,我需要单独调用它的房间.它有效,但这是一个额外的电话.(想象一下我试图把很多东西包在一起!)

现在,如果我有100个房子,为了序列化所有内容,我需要在O(n)时间内进行100次数据库命中

如果我可以将所有信息放在一起,我知道我可以减少到2次点击.O(1)时间

my_houses = Houses.objects.filter(name = …
Run Code Online (Sandbox Code Playgroud)

python django django-rest-framework

7
推荐指数
1
解决办法
5345
查看次数

Django - 序列化器中的源代码导致过多的数据库调用

我想在Django中创建一个歌曲 - 艺术家 - 专辑关系.我有以下型号:

class Artist(models.Model):
    gid = models.CharField(max_length=63, blank=True)
    name = models.CharField(max_length=255, blank=True)
    begin_life = models.CharField(max_length=31, blank=True)
    end_life = models.CharField(max_length=31, blank=True)
    type = models.CharField(max_length=1, blank=True)
    gender = models.CharField(max_length=1, blank=True)

class Song(models.Model):
    gid = models.CharField(max_length=63, blank=True)
    title = models.CharField(max_length=255, blank=True)
    artist = models.ForeignKey('Artist', related_name='songs_artist')
    album = models.ForeignKey('Album', related_name='songs_album')
    length = models.IntegerField(default=0)
Run Code Online (Sandbox Code Playgroud)

我创建了ArtistSerializer,以便在获取任何特定艺术家的信息时可以检索艺术家的所有歌曲.这是我创建的序列化程序:

class ArtistSerializer(serializers.ModelSerializer):
    songs_artist = SongSerializer(source='songs_artist')
    class Meta:
        model = Artist
        fields = ('name', 'type', 'gender', 'begin_life', 'end_life', 'songs_artist')

class SongSerializer(serializers.ModelSerializer):
    artist = SongArtistSerializer()
    album = SongAlbumSerializer()
    class …
Run Code Online (Sandbox Code Playgroud)

python django django-rest-framework

6
推荐指数
1
解决办法
1098
查看次数

如何使用 Django Rest Framework 序列化程序构建我的 JSON 响应?

我有一个数据库表:

servicenumber | meternumber | usagedatetime | usage
11111         | 22222       | 2019-01-01    | 1.85
11111         | 22222       | 2019-01-02    | 2.25
11111         | 22222       | 2019-01-03    | 1.55
11111         | 22222       | 2019-01-04    | 2.15
11111         | 33333       | 2019-02-01    | 2.95
11111         | 33333       | 2019-02-02    | 3.95
11111         | 33333       | 2019-02-03    | 2.05
11111         | 33333       | 2019-02-04    | 3.22
Run Code Online (Sandbox Code Playgroud)

如您所见,一个服务编号可以与多个仪表编号相关联。将服务编号视为不变的地理位置的唯一标识符。

我有一个 Django 模型:

class MeterUsage(models.Model):

    objectid = models.IntegerField(
        db_column='OBJECTID', unique=True, primary_key=True)

    servicenumber = models.IntegerField(
        db_column='serviceNumber', …
Run Code Online (Sandbox Code Playgroud)

python django serialization django-rest-framework

5
推荐指数
1
解决办法
1180
查看次数

Django REST Serializer做N + 1数据库调用多个嵌套关系,3个级别

我有一种情况,我的模型有外键关系:

# models.py
class Child(models.Model):
    parent = models.ForeignKey(Parent,)

class Parent(models.Model):
    pass
Run Code Online (Sandbox Code Playgroud)

和我的序列化器:

class ParentSerializer(serializer.ModelSerializer):
    child = serializers.SerializerMethodField('get_children_ordered')

    def get_children_ordered(self, parent):
        queryset = Child.objects.filter(parent=parent).select_related('parent')
        serialized_data = ChildSerializer(queryset, many=True, read_only=True, context=self.context)
        return serialized_data.data

    class Meta:
        model = Parent
Run Code Online (Sandbox Code Playgroud)

当我在N个父母的视图中调用Parent时,Django在抓取子节点时在序列化器内进行N次数据库调用.有没有办法让所有的孩子为所有家长最小化数据库呼叫的数量?

我试过这个,但它似乎没有解决我的问题:

class ParentList(generics.ListAPIView):

    def get_queryset(self):
        queryset = Parent.objects.prefetch_related('child')
        return queryset

    serializer_class = ParentSerializer
    permission_classes = (permissions.IsAuthenticated,)
Run Code Online (Sandbox Code Playgroud)

编辑

我已经更新了下面的代码以反映Alex的反馈....它解决了一个嵌套关系的N + 1.

# serializer.py
class ParentSerializer(serializer.ModelSerializer):
    child = serializers.SerializerMethodField('get_children_ordered')

    def get_children_ordered(self, parent):
        # The all() call should hit the cache
        serialized_data = ChildSerializer(parent.child.all(), many=True, read_only=True, …
Run Code Online (Sandbox Code Playgroud)

django polymorphism django-models django-rest-framework

4
推荐指数
1
解决办法
2459
查看次数

Django Rest框架ModelSerializer运行太慢

我们想为我们的 django 项目提供一个 api,所以我们使用 drf (django Rest Framework)。我们使用 ModelSerializer,它提供了一种快捷方式,可让您自动创建一个具有与模型字段对应的字段的序列化器类。我们的问题是它运行得很慢。换句话说,序列化过程大约需要 40 秒才能检索到响应。

我们怎样才能减少这种延迟呢?
看法

class MyObjViewSet(viewsets.ModelViewSet):

    pagination_class = LargeResultsSetPagination

    def get_queryset(self):
        queryset = MyObj.objects.all().order_by('time')
        return queryset

    serializer_class = MyObjSerializer
Run Code Online (Sandbox Code Playgroud)

我的对象模型

class MyObj(models.Model):
    id = models.BigIntegerField(primary_key=True)
    time = models.DateTimeField()
    type = models.CharField(max_length=5)
    user = models.ForeignKey('User', related_name='myobj')
Run Code Online (Sandbox Code Playgroud)

MyObj 用户模型

class User(models.Model):
    id = models.IntegerField(primary_key=True)
    username = models.CharField(max_length=80)
Run Code Online (Sandbox Code Playgroud)

我的 Obj 序列化器

class MyObjSerializer(serializers.ModelSerializer):

    class Meta:
        model = MyObj
        fields = ('id', 'type', 'time', 'user')
Run Code Online (Sandbox Code Playgroud)

我的问题是,当我想检索 obj 列表时,大约需要 40 秒!

django performance django-rest-framework

3
推荐指数
1
解决办法
5057
查看次数