簡體   English   中英

Django預取相關的預取相關

[英]Django prefetch related of prefetched related

我有一些兒童親子關系的模特兒。 在我的views.py中,我做了swsallsteps = sws_dcoument_step.objects.filter().prefetch_related(my various models)

我遇到的問題是如何從相關信息中預取相關信息? 我迷失在這一部分。 示例我在views.py中有這個

  swsallsteps = SWS_Document_Step.objects\
      .filter(document_number=document_id)\
      .prefetch_related('swes_step_set', 'sws_step_hazard_set', 'sws_step_ppe_set')

這正是我所期待的。 與SWS_Document_Step相關聯的SWES_Step_Set就像我下面的前兩個模型一樣。 但是,我可以拉出與SWES_Document_Step相關聯的SWES_Step_Picture模型嗎? 我想它比我做的簡單得多。

模型例如如下。

class SWS_Document_Step(models.Model):

    STEP_TYPE_CHOICES = (
        ('People', 'People'),
        ('Quality', 'Quality'),
        ('Velocity', 'Velocity'),
        ('Cost', 'Cost'),
    )
    document_number = models.ForeignKey(SWS_Document, on_delete=models.CASCADE)
    sws_sequence_number = models.PositiveIntegerField(editable=True, null=True)
    sws_work_element_description = models.CharField(max_length=500)
    sws_step_type = models.CharField(max_length=30, choices=STEP_TYPE_CHOICES, null=True, blank=True)
    pub_date = models.DateTimeField(auto_now=True)

    class Meta:
        verbose_name = 'SWS Document Step'
        verbose_name_plural = '005 SWS Document Steps'

    def __str__(self):
        return str(self.document_number) + " " + str(self.sws_sequence_number) + " " + str(self.sws_work_element_description)

class SWES_Step(models.Model):

    STEP_TYPE_CHOICES = (
        ('People', 'People'),
        ('Quality', 'Quality'),
        ('Velocity', 'Velocity'),
        ('Cost', 'Cost'),
    )
    sws_document_id = models.ForeignKey(SWS_Document_Step, on_delete=models.CASCADE, null=True)
    swes_description = models.CharField(max_length=500)
    swes_step_type = models.CharField(max_length=8, choices=STEP_TYPE_CHOICES, blank=True)
    pub_date = models.DateTimeField(auto_now=True)

    class Meta:
        verbose_name = 'SWES Step'
        verbose_name_plural = '012 SWES Document Steps'

    def __str__(self):
        return str(self.sws_document_id) + " " + str(self.swes_description)

class SWES_Step_Picture(models.Model):

    swes_step = models.ForeignKey(SWES_Step, on_delete=models.CASCADE)
    sws_step_photo = models.ImageField()
    pub_date = models.DateTimeField(auto_now=True)

    class Meta:
        verbose_name = 'SWES Step Picture'
        verbose_name_plural = '015 SWES Step Pictures'
>>> from django_single.models import *
>>> SWSDocumentStep.objects.select_related('document_number').prefetch_related('swesstep_set', 'swesstep_set__swessteppicture_set')
DEBUG (0.004) SELECT "django_single_swsdocumentstep"."id", "django_single_swsdocumentstep"."document_number_id", "django_single_swsdocumentstep"."sws_sequence_number", "django_single_swsdocumentstep"."sws_work_element_description", "django_single_swsdocumentstep"."sws_step_type", "django_single_swsdocumentstep"."pub_date", "django_single_swsdocument"."id", "django_single_swsdocument"."name" FROM "django_single_swsdocumentstep" INNER JOIN "django_single_swsdocument" ON ("django_single_swsdocumentstep"."document_number_id" = "django_single_swsdocument"."id") WHERE "django_single_swsdocumentstep"."id" = 10  LIMIT 21; args=(10,)
DEBUG (0.001) SELECT "django_single_swesstep"."id", "django_single_swesstep"."sws_document_id", "django_single_swesstep"."swes_description", "django_single_swesstep"."swes_step_type", "django_single_swesstep"."pub_date" FROM "django_single_swesstep" WHERE "django_single_swesstep"."sws_document_id" IN (10); args=(10,)
DEBUG (0.002) SELECT "django_single_swessteppicture"."id", "django_single_swessteppicture"."swes_step_id", "django_single_swessteppicture"."pub_date" FROM "django_single_swessteppicture" WHERE "django_single_swessteppicture"."swes_step_id" IN (10); args=(10,)
<QuerySet [<SWSDocumentStep: SWSDocument object (10) None >]>

抱歉,無法重命名您的模型,它們是不做的示例:

1. 不要使用ForeignKey並將_id添加到模型的末尾,例如: sws_document_id > sws_document

2.在python中,我們不在類中添加_ ,例如: SWES_Step_Picture > SWESStepPicture

# to get this to work you will need to do the following steps
mkdir django_simple/migrations
touch django_simple/django_simple.py
# copy and paste the content of the file bellow in django_simple/django_simple.py
python django_simple/django_simple.py makemigrations
python django_simple/django_simple.py migrate
python django_simple/django_simple.py shell -c 'from django_simple.models import *; SWESStepPicture.objects.create(swes_step=SWESStep.objects.create(sws_document=SWSDocumentStep.objects.create(document_number=SWSDocument.objects.create(name="blah"))))'
#!/usr/bin/env python
# -*- coding:utf-8 -*-

# Stolen from: https://mlvin.xyz/django-single-file-project.html

import inspect
from types import ModuleType
import os
import sys
from django.conf import settings
BASE_DIR = os.path.dirname(os.path.abspath(__file__))

sys.path[0] = os.path.dirname(BASE_DIR)

# the current folder name will also be our app
APP_LABEL = os.path.basename(BASE_DIR)


settings.configure(
    DEBUG=True,
    ROOT_URLCONF=__name__,
    MIDDLEWARE=[],
    INSTALLED_APPS=[
        APP_LABEL,
        'django.contrib.contenttypes',
    ],
    DATABASES={
        'default': {
            'ENGINE': 'django.db.backends.sqlite3',
            'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
        }
    },
    LOGGING={
        'version': 1,
        'disable_existing_loggers': False,
        'formatters': {
            'simple': {
                'format': "%(levelname)s %(message)s",
            },
        },
        'handlers': {
            'console': {
                'level': 'DEBUG',
                'class': 'logging.StreamHandler',
                'formatter': 'simple',
            }
        },
        'loggers': {
            'django.db.backends': {'handlers': ['console'], 'level': 'DEBUG', 'propagate': False},
            'django.db.backends.schema': {'level': 'ERROR'},  # Causes sql logs to duplicate -- really annoying
        }
    }
)


import django
django.setup()

from django.db import models

# Create your models here.


class SWSDocument(models.Model):
    name = models.CharField(max_length=30)

    class Meta:
        verbose_name = 'SWS Document'
        verbose_name_plural = '001 SWS Document'
        app_label = APP_LABEL


class SWSDocumentStep(models.Model):

    STEP_TYPE_CHOICES = (
        ('People', 'People'),
        ('Quality', 'Quality'),
        ('Velocity', 'Velocity'),
        ('Cost', 'Cost'),
    )
    document_number = models.ForeignKey(SWSDocument, on_delete=models.CASCADE)
    sws_sequence_number = models.PositiveIntegerField(editable=True, null=True)
    sws_work_element_description = models.CharField(max_length=500)
    sws_step_type = models.CharField(max_length=30, choices=STEP_TYPE_CHOICES, null=True, blank=True)
    pub_date = models.DateTimeField(auto_now=True)

    class Meta:
        verbose_name = 'SWS Document Step'
        verbose_name_plural = '005 SWS Document Steps'
        app_label = APP_LABEL

    def __str__(self):
        return str(self.document_number) + " " + str(self.sws_sequence_number) + " " + str(self.sws_work_element_description)


class SWESStep(models.Model):

    STEP_TYPE_CHOICES = (
        ('People', 'People'),
        ('Quality', 'Quality'),
        ('Velocity', 'Velocity'),
        ('Cost', 'Cost'),
    )
    sws_document = models.ForeignKey(SWSDocumentStep, on_delete=models.CASCADE, null=True)
    swes_description = models.CharField(max_length=500)
    swes_step_type = models.CharField(max_length=8, choices=STEP_TYPE_CHOICES, blank=True)
    pub_date = models.DateTimeField(auto_now=True)

    class Meta:
        verbose_name = 'SWES Step'
        verbose_name_plural = '012 SWES Document Steps'
        app_label = APP_LABEL

    def __str__(self):
        return str(self.sws_document_id) + " " + str(self.swes_description)


class SWESStepPicture(models.Model):

    swes_step = models.ForeignKey(SWESStep, on_delete=models.CASCADE)
    # sws_step_photo = models.ImageField()  # too lazy to install pillow
    pub_date = models.DateTimeField(auto_now=True)

    class Meta:
        verbose_name = 'SWES Step Picture'
        verbose_name_plural = '015 SWES Step Pictures'
        app_label = APP_LABEL


# Can't use `dumpdata` without it -- this will set it for ALL apps, the app_config is shared
SWESStepPicture._meta.app_config.models_module = '__main__'

# Used so you can do 'from <name of file>.models import *'
models_module = ModuleType(APP_LABEL + '.models')
for variable_name, value in list(locals().items()):
    # We are only interested in models
    if inspect.isclass(value) and issubclass(value, models.Model):
        setattr(models_module, variable_name, value)
sys.modules[models_module.__name__] = models_module

urlpatterns = []

if __name__ == "__main__":
    from django.core.management import execute_from_command_line
    execute_from_command_line(sys.argv)
else:
    from django.core.wsgi import get_wsgi_application
    get_wsgi_application()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM