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)
比方说,块b1有g1组.根据它的名字,我想从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对象,它不可迭代.
该怎么办?怎么了?
我正在为我的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) 我在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
我有一个 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
我想知道如何在序列化时减少对数据库的调用次数:
我有以下两种型号:
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) 我想在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) 我有一个数据库表:
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) 我有一种情况,我的模型有外键关系:
# 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 项目提供一个 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 秒!