Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/pre-commit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ jobs:
pre-commit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
- uses: pre-commit/action@v3.0.0
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
- uses: pre-commit/action@v3.0.1
18 changes: 9 additions & 9 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,18 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest]
python-version: ['3.8', '3.9', '3.10', '3.11']
django-version: ['3.2', '4.0', '4.1', '4.2']
python-version: ['3.10', '3.11', '3.12', '3.13']
django-version: ['4.2', '5.0', '5.1', '5.2']

steps:
- name: Checkout code
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Cache installed requirements
uses: actions/cache@v3
uses: actions/cache@v4
with:
path: ${{ env.pythonLocation }}
key: ${{ runner.os }}-python-${{ env.pythonLocation }}-${{ hashFiles('pyproject.toml') }}-test-v01
Expand All @@ -37,19 +37,19 @@ jobs:
DJANGO: ${{ matrix.django-version }}
run: tox
- name: Run tests for example
if: ${{ matrix.os == 'ubuntu-latest' && matrix.python-version == '3.8' && matrix.django-version == '3.2' }}
if: ${{ matrix.os == 'ubuntu-latest' && matrix.python-version == '3.10' && matrix.django-version == '4.2' }}
run: |
python -m pip install .[test,example]
python -m pytest example
- name: Generate coverage.xml
if: ${{ matrix.os == 'ubuntu-latest' && matrix.python-version == '3.8' && matrix.django-version == '3.2' }}
uses: actions/upload-artifact@v3
if: ${{ matrix.os == 'ubuntu-latest' && matrix.python-version == '3.10' && matrix.django-version == '4.2' }}
uses: actions/upload-artifact@v4
with:
name: tox-gh-actions-coverage
path: coverage.xml
if-no-files-found: error
- name: Upload coverage.xml to Coveralls
if: ${{ matrix.os == 'ubuntu-latest' && matrix.python-version == '3.8' && matrix.django-version == '3.2' }}
if: ${{ matrix.os == 'ubuntu-latest' && matrix.python-version == '3.10' && matrix.django-version == '4.2' }}
run: coveralls --service=github
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,14 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.3.0]

- Include `py.typed` file for type hints
- Add support to Python 3.12 and 3.13
- Drop support to Python 3.8 and 3.9
- Add support to Django 5.0, 5.1, and 5.2
- Drop support to Django 3.2, 4.0, and 4.1

## [0.2.0]

- Add support to nested prefetch lookups like `v.VirtualModel(manager=User.objects, lookup="course__facilitators")`
Expand Down
2 changes: 1 addition & 1 deletion django_virtual_models/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""Top-level package for django_virtual_models."""
import logging

__version__ = "0.2.0"
__version__ = "0.3.0"

# Good practice: https://docs.python-guide.org/writing/logging/#logging-in-a-library
logging.getLogger(__name__).addHandler(logging.NullHandler())
Expand Down
Empty file added django_virtual_models/py.typed
Empty file.
26 changes: 23 additions & 3 deletions django_virtual_models/query_capture/capture.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,27 @@
import time
import typing
from contextlib import ContextDecorator, ExitStack
from distutils.sysconfig import get_python_lib

from django.conf import settings
from django.db import connection

try:
from distutils.sysconfig import get_python_lib
except ImportError:
from sysconfig import get_paths

def get_python_lib(plat_specific=False):
"""
Get the path to the Python library directory.
If plat_specific is True, return platform-specific directory,
otherwise return platform-independent directory.
To match distutils behavior, return both paths when called without arguments.
"""
paths = get_paths()
if plat_specific:
return paths["platlib"]
return [paths["purelib"], paths["platlib"]]


class CapturedQuery(typing.TypedDict):
"""
Expand Down Expand Up @@ -79,11 +95,15 @@ def _save_queries(self, execute, sql, params, many, context):
"""
if settings.DEBUG:
# only calculate stack in DEBUG or TEST mode, to avoid production impact
python_library_directory = get_python_lib()
python_lib_paths = get_python_lib()
# Handle both single string and list return values
if isinstance(python_lib_paths, str):
python_lib_paths = [python_lib_paths]

stack = [
stack
for stack in inspect.stack()
if not stack.filename.startswith(python_library_directory)
if not any(stack.filename.startswith(path) for path in python_lib_paths)
and not stack.filename.startswith("/usr/local/lib/")
and not stack.filename.endswith("query_capture/capture.py")
]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Generated by Django 5.2 on 2025-05-14 01:36

from django.db import migrations


class Migration(migrations.Migration):
dependencies = [
("movies", "0001_initial"),
]

operations = [
migrations.RenameIndex(
model_name="persondirector",
new_name="movies_pers_movie_i_957f84_idx",
old_fields=("movie", "order"),
),
]
2 changes: 1 addition & 1 deletion example/movies/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class PersonDirector(models.Model):
order = models.PositiveSmallIntegerField()

class Meta:
index_together = [("movie", "order")]
indexes = [models.Index(fields=["movie", "order"])]
ordering = ["movie", "order"]


Expand Down
27 changes: 14 additions & 13 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ build-backend = "flit_core.buildapi"

[tool.flit.module]
name = "django_virtual_models"
py-typed = true

[project]
name = "django-virtual-models"
Expand All @@ -21,13 +22,13 @@ classifiers = [
"License :: OSI Approved :: MIT License",
"Natural Language :: English",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
]
dependencies = [
"django >=3.2",
"django >=4.2",
"djangorestframework >=3.13.1",
"typing-extensions >=4.3.0",
]
Expand Down Expand Up @@ -57,7 +58,7 @@ test = [
"model_bakery >=1.11.0,<2.0.0",
]
example = [
"django >= 3.2,<4.0",
"django >= 4.2,<6.0",
"pyyaml >= 6.0,<7.0",
]

Expand Down Expand Up @@ -112,31 +113,31 @@ testpaths = [
[tool.tox]
legacy_tox_ini = """
[tox]
envlist = {linux}-py{38,39,310,311}-django{32,40,41,42}
envlist = {linux}-py{310,311,312,313}-django{42,50,51,52}
isolated_build = True

[gh-actions]
python =
3.8: py38
3.9: py39
3.10: py310
3.11: py311
3.12: py312
3.13: py313

[gh-actions:env]
OS =
ubuntu-latest: linux
DJANGO =
3.2: django32
4.0: django40
4.1: django41
4.2: django42
5.0: django50
5.1: django51
5.2: django52

[testenv]
deps =
django32: django~=3.2
django40: django~=4.0
django41: django~=4.1
django42: django~=4.2
django50: django~=5.0
django51: django~=5.1
django52: django~=5.2
.[test]
commands =
coverage run -m pytest --basetemp={envtmpdir}
Expand Down
Loading