diff --git a/bin/freenit.sh b/bin/freenit.sh
index 1c6a08d..540ac36 100755
--- a/bin/freenit.sh
+++ b/bin/freenit.sh
@@ -663,17 +663,17 @@ EOF
EOF
- mkdir -p src/routes/jabber
- cat >src/routes/jabber/+page.svelte<src/routes/chat/+page.svelte<
- import { Jabber } from 'freenit'
+ import { Chat } from 'freenit'
- Jabber
+ Chat
-
+
EOF
mkdir -p src/routes/calendar
diff --git a/freenit/api/blog.py b/freenit/api/blog.py
new file mode 100644
index 0000000..155a2ca
--- /dev/null
+++ b/freenit/api/blog.py
@@ -0,0 +1,358 @@
+from datetime import datetime
+from html import escape
+
+import pydantic
+from fastapi import Depends, Header, HTTPException, Request, Response
+
+from freenit.api.router import route
+from freenit.decorators import description
+from freenit.models.blog import BlogPost, BlogPostOptional, BlogPostTag, NotFoundError, Tag
+from freenit.models.pagination import Page, paginate
+from freenit.models.user import User
+from freenit.permissions import blog_perms
+
+tags = ["blog"]
+
+
+# ---------------------------------------------------------------------------
+# Request / response schemas
+# ---------------------------------------------------------------------------
+
+
+class BlogPostCreate(pydantic.BaseModel):
+ title: str
+ slug: str
+ content: str
+ date: datetime | None = None
+ published: bool = False
+ tags: list[str] = []
+
+
+class BlogPostUpdate(pydantic.BaseModel):
+ model_config = pydantic.ConfigDict(extra="forbid")
+
+ title: str | None = None
+ slug: str | None = None
+ content: str | None = None
+ date: datetime | None = None
+ published: bool | None = None
+ tags: list[str] | None = None
+
+
+class BlogPostResponse(pydantic.BaseModel):
+ model_config = pydantic.ConfigDict(from_attributes=True)
+
+ id: int
+ title: str
+ slug: str
+ content: str
+ date: datetime | None = None
+ published: bool
+ author_id: int | None = None
+ tags: list[str] = []
+ created_at: datetime | None = None
+ updated_at: datetime | None = None
+
+
+class PublicBlogPostResponse(pydantic.BaseModel):
+ model_config = pydantic.ConfigDict(from_attributes=True)
+
+ id: int
+ title: str
+ slug: str
+ content: str
+ date: datetime | None = None
+ author_id: int | None = None
+ tags: list[str] = []
+ created_at: datetime | None = None
+ updated_at: datetime | None = None
+
+
+class TagResponse(pydantic.BaseModel):
+ model_config = pydantic.ConfigDict(from_attributes=True)
+
+ id: int
+ name: str
+
+
+# ---------------------------------------------------------------------------
+# Helpers
+# ---------------------------------------------------------------------------
+
+
+async def _get_post(id: int) -> BlogPost:
+ try:
+ return await BlogPost.objects.get(id=id)
+ except NotFoundError:
+ raise HTTPException(status_code=404, detail="No such blog post")
+
+
+async def _get_post_by_slug(slug: str) -> BlogPost:
+ try:
+ return await BlogPost.objects.filter(slug=slug).get()
+ except NotFoundError:
+ raise HTTPException(status_code=404, detail="No such blog post")
+
+
+async def _get_tag(name: str) -> Tag:
+ try:
+ return await Tag.objects.filter(name=name).get()
+ except NotFoundError:
+ raise HTTPException(status_code=404, detail="No such tag")
+
+
+async def _check_slug_unique(slug: str, exclude_id: int | None = None) -> None:
+ existing = await BlogPost.objects.filter(slug=slug).all()
+ if any(item.id != exclude_id for item in existing):
+ raise HTTPException(status_code=409, detail="Blog post slug already exists")
+
+
+async def _set_post_tags(post: BlogPost, tag_names: list[str]) -> None:
+ existing = await BlogPostTag.objects.filter(post_id=post.id).all()
+ for link in existing:
+ await link.delete()
+
+ tag_objects = []
+ for name in set(tag_names):
+ name = name.strip().lower()
+ if not name:
+ continue
+ try:
+ tag = await Tag.objects.filter(name=name).get()
+ except NotFoundError:
+ tag = await Tag.objects.create(name=name)
+ tag_objects.append(tag)
+
+ for tag in tag_objects:
+ try:
+ await BlogPostTag.objects.create(post_id=post.id, tag_id=tag.id)
+ except IntegrityError:
+ pass
+
+
+async def _get_post_tags(post_id: int) -> list[str]:
+ links = await BlogPostTag.objects.filter(post_id=post_id).all()
+ if not links:
+ return []
+ tag_ids = [link.tag_id for link in links]
+ tag_objects = await Tag.objects.filter(id__in=tag_ids).all()
+ return sorted(tag.name for tag in tag_objects)
+
+
+def _post_response(post: BlogPost, tag_names: list[str] | None = None) -> BlogPostResponse:
+ if tag_names is None:
+ # Tags should be populated before calling; this is a synchronous helper.
+ tag_names = []
+ data = BlogPostResponse.model_validate(post).model_dump()
+ data["tags"] = tag_names
+ return BlogPostResponse(**data)
+
+
+async def _enforce_author_or_admin(post: BlogPost, user: User) -> None:
+ if not user.admin and post.author_id != user.id:
+ raise HTTPException(
+ status_code=403, detail="Only the author or admin can modify this post"
+ )
+
+
+def _rfc822_date(value: datetime | None) -> str:
+ if value is None:
+ return ""
+ return value.strftime("%a, %d %b %Y %H:%M:%S GMT")
+
+
+# ---------------------------------------------------------------------------
+# Admin blog posts
+# ---------------------------------------------------------------------------
+
+
+@route("/blog", tags=tags)
+class BlogPostListAPI:
+ @staticmethod
+ @description("Get blog posts")
+ async def get(
+ page: int = Header(default=1),
+ perpage: int = Header(default=10),
+ _: User = Depends(blog_perms),
+ ) -> Page[BlogPostResponse]:
+ result = await paginate(BlogPost.objects.order_by("-date"), page, perpage)
+ for item in result.data:
+ tag_names = await _get_post_tags(item.id)
+ object.__setattr__(item, "tags", tag_names)
+ return result
+
+ @staticmethod
+ @description("Create blog post")
+ async def post(
+ data: BlogPostCreate,
+ user: User = Depends(blog_perms),
+ ) -> BlogPostResponse:
+ await _check_slug_unique(data.slug)
+ now = datetime.utcnow()
+ post_date = data.date or now
+ post = await BlogPost.objects.create(
+ title=data.title,
+ slug=data.slug,
+ content=data.content,
+ date=post_date,
+ published=data.published,
+ author_id=user.id,
+ created_at=now,
+ updated_at=now,
+ )
+ await _set_post_tags(post, data.tags)
+ tag_names = await _get_post_tags(post.id)
+ return _post_response(post, tag_names)
+
+
+# ---------------------------------------------------------------------------
+# Public blog posts
+# ---------------------------------------------------------------------------
+
+
+@route("/blog/public", tags=tags)
+class BlogPostPublicListAPI:
+ @staticmethod
+ @description("Get published blog posts")
+ async def get(
+ page: int = Header(default=1),
+ perpage: int = Header(default=10),
+ ) -> Page[PublicBlogPostResponse]:
+ query = BlogPost.objects.filter(published=True).order_by("-date")
+ result = await paginate(query, page, perpage)
+ for item in result.data:
+ tag_names = await _get_post_tags(item.id)
+ object.__setattr__(item, "tags", tag_names)
+ return result
+
+
+@route("/blog/public/{slug}", tags=tags)
+class BlogPostPublicDetailAPI:
+ @staticmethod
+ @description("Get published blog post")
+ async def get(slug: str) -> PublicBlogPostResponse:
+ post = await _get_post_by_slug(slug)
+ if not post.published:
+ raise HTTPException(status_code=404, detail="No such blog post")
+ tag_names = await _get_post_tags(post.id)
+ object.__setattr__(post, "tags", tag_names)
+ return PublicBlogPostResponse.model_validate(post)
+
+
+@route("/blog/tags", tags=tags)
+class BlogTagListAPI:
+ @staticmethod
+ @description("Get blog tags")
+ async def get() -> list[TagResponse]:
+ return await Tag.objects.order_by("name").all()
+
+
+@route("/blog/tags/{name}/posts", tags=tags)
+class BlogTagPostsAPI:
+ @staticmethod
+ @description("Get published blog posts by tag")
+ async def get(
+ name: str,
+ page: int = Header(default=1),
+ perpage: int = Header(default=10),
+ ) -> Page[PublicBlogPostResponse]:
+ tag = await _get_tag(name.lower())
+ links = await BlogPostTag.objects.filter(tag_id=tag.id).all()
+ post_ids = [link.post_id for link in links]
+ if not post_ids:
+ return Page(data=[], page=page, perpage=perpage, pages=0, total=0)
+ query = BlogPost.objects.filter(id__in=post_ids, published=True).order_by("-date")
+ result = await paginate(query, page, perpage)
+ for item in result.data:
+ tag_names = await _get_post_tags(item.id)
+ object.__setattr__(item, "tags", tag_names)
+ return result
+
+
+# ---------------------------------------------------------------------------
+# RSS feed
+# ---------------------------------------------------------------------------
+
+
+@route("/blog/rss", tags=tags)
+class BlogRssAPI:
+ @staticmethod
+ @description("Get blog RSS feed")
+ async def get(request: Request) -> Response:
+ posts = await BlogPost.objects.filter(published=True).order_by("-date").limit(20).all()
+ host = request.base_url.netloc
+ blog_url = f"{request.base_url.scheme}://{host}/blog"
+ now = datetime.utcnow()
+
+ items = []
+ for post in posts:
+ post_url = f"{blog_url}/{post.slug}"
+ tag_names = await _get_post_tags(post.id)
+ categories = "".join(
+ f"{escape(tag)}" for tag in tag_names
+ )
+ items.append(
+ f"""
+ -
+ {escape(post.title)}
+ {escape(post_url)}
+ {escape(post_url)}
+ {_rfc822_date(post.date)}
+ {categories}
+ {escape(post.content)}
+
"""
+ )
+
+ rss = f"""
+
+
+ {escape("Blog")}
+ {escape(blog_url)}
+ {escape("Latest blog posts")}
+ {_rfc822_date(now)}
+ {''.join(items)}
+
+
+"""
+ return Response(content=rss, media_type="application/rss+xml")
+
+
+# ---------------------------------------------------------------------------
+# Blog post details (must be registered after static /blog/... routes)
+# ---------------------------------------------------------------------------
+
+
+@route("/blog/{id}", tags=tags)
+class BlogPostDetailAPI:
+ @staticmethod
+ async def get(id: int, _: User = Depends(blog_perms)) -> BlogPostResponse:
+ post = await _get_post(id)
+ tag_names = await _get_post_tags(post.id)
+ return _post_response(post, tag_names)
+
+ @staticmethod
+ async def patch(
+ id: int,
+ data: BlogPostUpdate,
+ user: User = Depends(blog_perms),
+ ) -> BlogPostResponse:
+ post = await _get_post(id)
+ await _enforce_author_or_admin(post, user)
+ if data.slug:
+ await _check_slug_unique(data.slug, exclude_id=id)
+ update = data.model_dump(exclude_none=True)
+ if "tags" in update:
+ await _set_post_tags(post, update.pop("tags"))
+ if update:
+ await post.patch(BlogPostOptional(**update))
+ tag_names = await _get_post_tags(post.id)
+ return _post_response(post, tag_names)
+
+ @staticmethod
+ async def delete(id: int, user: User = Depends(blog_perms)) -> BlogPostResponse:
+ post = await _get_post(id)
+ await _enforce_author_or_admin(post, user)
+ tag_names = await _get_post_tags(post.id)
+ response = _post_response(post, tag_names)
+ await post.delete()
+ return response
diff --git a/freenit/api/jabber.py b/freenit/api/chat.py
similarity index 67%
rename from freenit/api/jabber.py
rename to freenit/api/chat.py
index af69a3e..3cb6679 100644
--- a/freenit/api/jabber.py
+++ b/freenit/api/chat.py
@@ -4,11 +4,11 @@
from freenit.permissions import profile_perms
config = getConfig()
-tags = ["jabber"]
+tags = ["chat"]
-@api.get("/jabber/config", tags=tags)
-async def jabber_config(user=Depends(profile_perms)):
+@api.get("/chat/config", tags=tags)
+async def chat_config(user=Depends(profile_perms)):
return {
"ws_url": config.xmpp.ws_url,
}
diff --git a/freenit/api/git.py b/freenit/api/git.py
index 32916e2..9379215 100644
--- a/freenit/api/git.py
+++ b/freenit/api/git.py
@@ -11,6 +11,7 @@
from freenit.decorators import description
from freenit.git import repo as git_repo
from freenit.git import store
+from freenit.git.webhook import notify_push
from freenit.models.git import GitPermission, GitPushLog, GitRepo
from freenit.models.pagination import Page
from freenit.models.user import User
@@ -40,6 +41,7 @@ class GitRepoCreate(pydantic.BaseModel):
default_branch: str = "main"
tests_enabled: bool = False
test_command: str | None = None
+ webhook_url: str | None = None
class GitRepoUpdate(pydantic.BaseModel):
@@ -51,6 +53,7 @@ class GitRepoUpdate(pydantic.BaseModel):
default_branch: str | None = None
tests_enabled: bool | None = None
test_command: str | None = None
+ webhook_url: str | None = None
class GitRepoResponse(pydantic.BaseModel):
@@ -65,6 +68,7 @@ class GitRepoResponse(pydantic.BaseModel):
default_branch: str
tests_enabled: bool
test_command: str | None = None
+ webhook_url: str | None = None
created_at: datetime | None = None
updated_at: datetime | None = None
@@ -307,6 +311,7 @@ async def post(
background_tasks.add_task(_run_tests, repo, push_log)
else:
await store.update_push_status(push_log, "completed")
+ await notify_push(repo, data.ref, data.old_rev, data.new_rev, data.pusher_email)
return GitPushLogResponse.model_validate(push_log)
diff --git a/freenit/base_config.py b/freenit/base_config.py
index b1442ea..a84c91b 100644
--- a/freenit/base_config.py
+++ b/freenit/base_config.py
@@ -160,7 +160,8 @@ class BaseConfig:
project = "freenit.models.sql.project"
lms = "freenit.models.sql.lms"
git = "freenit.models.sql.git"
- modules = ["auth"]
+ blog = "freenit.models.sql.blog"
+ modules = ["auth", "blog"]
meta = None
auth = Auth()
mail = None
@@ -225,9 +226,10 @@ class TestConfig(BaseConfig):
"dav",
"mail",
"sieve",
- "jabber",
+ "chat",
"omemo",
"git",
+ "blog",
]
diff --git a/freenit/git/hooks.py b/freenit/git/hooks.py
index 99befe0..56a4ea3 100644
--- a/freenit/git/hooks.py
+++ b/freenit/git/hooks.py
@@ -20,6 +20,7 @@
from freenit.config import getConfig
from freenit.git import repo as git_repo
from freenit.git import store
+from freenit.git.webhook import notify_push
from freenit.models.git import GitRepo
config = getConfig()
@@ -173,6 +174,7 @@ async def post_receive(repo_name: str) -> int:
await _run_tests_detached(repo_name, push_log.id)
else:
await store.update_push_status(push_log, "completed")
+ await notify_push(repo, ref, old_rev, new_rev, _pusher_email())
await _record_task_refs(repo, old_rev, new_rev)
except Exception as exc:
_error(f"Failed to record push for {ref}: {exc}")
diff --git a/freenit/git/store_ldap.py b/freenit/git/store_ldap.py
index ec6ee23..16184eb 100644
--- a/freenit/git/store_ldap.py
+++ b/freenit/git/store_ldap.py
@@ -198,6 +198,9 @@ async def create_repo(**kwargs) -> GitRepo:
test_command = kwargs.get("test_command")
if test_command:
entry["gitTestCommand"] = test_command
+ webhook_url = kwargs.get("webhook_url")
+ if webhook_url:
+ entry["gitWebhookUrl"] = webhook_url
entry["createdAt"] = _ldap_dt(now)
entry["updatedAt"] = _ldap_dt(now)
@@ -217,6 +220,7 @@ async def create_repo(**kwargs) -> GitRepo:
default_branch=kwargs.get("default_branch", "main"),
tests_enabled=kwargs.get("tests_enabled", False),
test_command=test_command,
+ webhook_url=webhook_url,
created_at=now,
updated_at=now,
)
@@ -254,6 +258,12 @@ async def update_repo(repo: GitRepo, data) -> GitRepo:
entry["gitTestCommand"] = value
elif "gitTestCommand" in entry:
del entry["gitTestCommand"]
+ if "webhook_url" in fields:
+ value = fields["webhook_url"]
+ if value:
+ entry["gitWebhookUrl"] = value
+ elif "gitWebhookUrl" in entry:
+ del entry["gitWebhookUrl"]
entry["updatedAt"] = _ldap_dt(datetime.utcnow())
await entry.modify()
diff --git a/freenit/git/webhook.py b/freenit/git/webhook.py
new file mode 100644
index 0000000..7065f67
--- /dev/null
+++ b/freenit/git/webhook.py
@@ -0,0 +1,57 @@
+import logging
+from typing import Any
+
+import httpx
+
+from freenit.config import getConfig
+from freenit.git import repo as git_repo
+
+config = getConfig()
+log = logging.getLogger("git.webhook")
+
+
+def _clone_url(repo_name: str) -> str:
+ host = config.hostname
+ if config.port != 443 and config.port != 80:
+ host = f"{host}:{config.port}"
+ return f"https://{host}/git/{repo_name}"
+
+
+async def notify_push(
+ repo,
+ ref: str,
+ old_rev: str | None,
+ new_rev: str | None,
+ pusher_email: str,
+) -> None:
+ """Send a push event webhook payload to the repository's webhook URL."""
+ url = getattr(repo, "webhook_url", None)
+ if not url:
+ return
+
+ try:
+ commits = git_repo.walk_push_commits(repo.path, old_rev, new_rev)
+ except Exception as exc:
+ log.warning("Failed to read commits for webhook: %s", exc)
+ commits = []
+
+ payload: dict[str, Any] = {
+ "event": "push",
+ "repository": {
+ "id": repo.id,
+ "name": repo.name,
+ "url": _clone_url(repo.name),
+ },
+ "ref": ref,
+ "before": old_rev,
+ "after": new_rev,
+ "pusher": {"email": pusher_email},
+ "commits": commits,
+ }
+
+ try:
+ async with httpx.AsyncClient(timeout=30) as client:
+ response = await client.post(url, json=payload)
+ response.raise_for_status()
+ except Exception as exc:
+ log.warning("Webhook to %s failed: %s", url, exc)
diff --git a/freenit/models/blog.py b/freenit/models/blog.py
new file mode 100644
index 0000000..516abbd
--- /dev/null
+++ b/freenit/models/blog.py
@@ -0,0 +1,11 @@
+from freenit.config import getConfig
+
+config = getConfig()
+blog = config.get_model("blog")
+
+BlogPost = blog.BlogPost
+BlogPostOptional = blog.BlogPostOptional
+BlogPostTag = blog.BlogPostTag
+Tag = blog.Tag
+NotFoundError = blog.NotFoundError
+IntegrityError = blog.IntegrityError
diff --git a/freenit/models/ldap/git.py b/freenit/models/ldap/git.py
index d5fbc1a..767fd4d 100644
--- a/freenit/models/ldap/git.py
+++ b/freenit/models/ldap/git.py
@@ -58,6 +58,7 @@ class GitRepo(LDAPBaseModel):
default_branch: str = Field("main", description="Default branch name")
tests_enabled: bool = Field(False, description="Run tests on push")
test_command: str | None = Field(None, description="Shell command used for tests")
+ webhook_url: str | None = Field(None, description="URL to notify on push")
created_at: datetime | None = Field(None, description="Creation timestamp")
updated_at: datetime | None = Field(None, description="Last update timestamp")
@@ -74,6 +75,7 @@ def from_entry(cls, entry):
default_branch=_first(entry, "gitDefaultBranch", "main"),
tests_enabled=_bool(entry, "gitTestsEnabled", False),
test_command=_first(entry, "gitTestCommand"),
+ webhook_url=_first(entry, "gitWebhookUrl"),
created_at=_datetime(entry, "createdAt"),
updated_at=_datetime(entry, "updatedAt"),
)
@@ -157,6 +159,7 @@ class GitRepoCreate(BaseModel):
default_branch: str = "main"
tests_enabled: bool = False
test_command: str | None = None
+ webhook_url: str | None = None
class GitRepoUpdate(BaseModel):
@@ -168,3 +171,4 @@ class GitRepoUpdate(BaseModel):
default_branch: str | None = None
tests_enabled: bool | None = None
test_command: str | None = None
+ webhook_url: str | None = None
diff --git a/freenit/models/sql/base.pyi b/freenit/models/sql/base.pyi
index 5c1a8c1..1298971 100644
--- a/freenit/models/sql/base.pyi
+++ b/freenit/models/sql/base.pyi
@@ -10,7 +10,6 @@ from oxyde import Model
from oxyde.queries import Query, QueryManager
from __future__ import annotations
-from typing import ClassVar
import oxyde
import pydantic
from fastapi import HTTPException
@@ -1642,1066 +1641,3 @@ class UserRoleManager(QueryManager[UserRole]):
"""Bulk update objects."""
...
-
-class Theme(Model):
- class Meta:
- is_table: bool
- table_name: str
- id: int | None
- name: str
- bg_color: str
- bg_secondary_color: str
- color_primary: str
- color_lightGrey: str
- color_grey: str
- color_darkGrey: str
- color_error: str
- color_success: str
- grid_maxWidth: str
- grid_gutter: str
- font_size: str
- font_color: str
- font_family_sans: str
- font_family_mono: str
- objects: ClassVar["ThemeManager"]
-
-
-class ThemeQuery(Query[Theme]):
- """Type-safe Query for Theme model."""
-
- # Query building methods (sync, return Query)
-
- def filter(
- self,
- *args: Any,
- bg_color: str | None = None,
- bg_color__contains: str | None = None,
- bg_color__icontains: str | None = None,
- bg_color__startswith: str | None = None,
- bg_color__istartswith: str | None = None,
- bg_color__endswith: str | None = None,
- bg_color__iendswith: str | None = None,
- bg_color__iexact: str | None = None,
- bg_color__in: list[str] | None = None,
- bg_color__isnull: bool | None = None,
- bg_secondary_color: str | None = None,
- bg_secondary_color__contains: str | None = None,
- bg_secondary_color__icontains: str | None = None,
- bg_secondary_color__startswith: str | None = None,
- bg_secondary_color__istartswith: str | None = None,
- bg_secondary_color__endswith: str | None = None,
- bg_secondary_color__iendswith: str | None = None,
- bg_secondary_color__iexact: str | None = None,
- bg_secondary_color__in: list[str] | None = None,
- bg_secondary_color__isnull: bool | None = None,
- color_darkGrey: str | None = None,
- color_darkGrey__contains: str | None = None,
- color_darkGrey__icontains: str | None = None,
- color_darkGrey__startswith: str | None = None,
- color_darkGrey__istartswith: str | None = None,
- color_darkGrey__endswith: str | None = None,
- color_darkGrey__iendswith: str | None = None,
- color_darkGrey__iexact: str | None = None,
- color_darkGrey__in: list[str] | None = None,
- color_darkGrey__isnull: bool | None = None,
- color_error: str | None = None,
- color_error__contains: str | None = None,
- color_error__icontains: str | None = None,
- color_error__startswith: str | None = None,
- color_error__istartswith: str | None = None,
- color_error__endswith: str | None = None,
- color_error__iendswith: str | None = None,
- color_error__iexact: str | None = None,
- color_error__in: list[str] | None = None,
- color_error__isnull: bool | None = None,
- color_grey: str | None = None,
- color_grey__contains: str | None = None,
- color_grey__icontains: str | None = None,
- color_grey__startswith: str | None = None,
- color_grey__istartswith: str | None = None,
- color_grey__endswith: str | None = None,
- color_grey__iendswith: str | None = None,
- color_grey__iexact: str | None = None,
- color_grey__in: list[str] | None = None,
- color_grey__isnull: bool | None = None,
- color_lightGrey: str | None = None,
- color_lightGrey__contains: str | None = None,
- color_lightGrey__icontains: str | None = None,
- color_lightGrey__startswith: str | None = None,
- color_lightGrey__istartswith: str | None = None,
- color_lightGrey__endswith: str | None = None,
- color_lightGrey__iendswith: str | None = None,
- color_lightGrey__iexact: str | None = None,
- color_lightGrey__in: list[str] | None = None,
- color_lightGrey__isnull: bool | None = None,
- color_primary: str | None = None,
- color_primary__contains: str | None = None,
- color_primary__icontains: str | None = None,
- color_primary__startswith: str | None = None,
- color_primary__istartswith: str | None = None,
- color_primary__endswith: str | None = None,
- color_primary__iendswith: str | None = None,
- color_primary__iexact: str | None = None,
- color_primary__in: list[str] | None = None,
- color_primary__isnull: bool | None = None,
- color_success: str | None = None,
- color_success__contains: str | None = None,
- color_success__icontains: str | None = None,
- color_success__startswith: str | None = None,
- color_success__istartswith: str | None = None,
- color_success__endswith: str | None = None,
- color_success__iendswith: str | None = None,
- color_success__iexact: str | None = None,
- color_success__in: list[str] | None = None,
- color_success__isnull: bool | None = None,
- font_color: str | None = None,
- font_color__contains: str | None = None,
- font_color__icontains: str | None = None,
- font_color__startswith: str | None = None,
- font_color__istartswith: str | None = None,
- font_color__endswith: str | None = None,
- font_color__iendswith: str | None = None,
- font_color__iexact: str | None = None,
- font_color__in: list[str] | None = None,
- font_color__isnull: bool | None = None,
- font_family_mono: str | None = None,
- font_family_mono__contains: str | None = None,
- font_family_mono__icontains: str | None = None,
- font_family_mono__startswith: str | None = None,
- font_family_mono__istartswith: str | None = None,
- font_family_mono__endswith: str | None = None,
- font_family_mono__iendswith: str | None = None,
- font_family_mono__iexact: str | None = None,
- font_family_mono__in: list[str] | None = None,
- font_family_mono__isnull: bool | None = None,
- font_family_sans: str | None = None,
- font_family_sans__contains: str | None = None,
- font_family_sans__icontains: str | None = None,
- font_family_sans__startswith: str | None = None,
- font_family_sans__istartswith: str | None = None,
- font_family_sans__endswith: str | None = None,
- font_family_sans__iendswith: str | None = None,
- font_family_sans__iexact: str | None = None,
- font_family_sans__in: list[str] | None = None,
- font_family_sans__isnull: bool | None = None,
- font_size: str | None = None,
- font_size__contains: str | None = None,
- font_size__icontains: str | None = None,
- font_size__startswith: str | None = None,
- font_size__istartswith: str | None = None,
- font_size__endswith: str | None = None,
- font_size__iendswith: str | None = None,
- font_size__iexact: str | None = None,
- font_size__in: list[str] | None = None,
- font_size__isnull: bool | None = None,
- grid_gutter: str | None = None,
- grid_gutter__contains: str | None = None,
- grid_gutter__icontains: str | None = None,
- grid_gutter__startswith: str | None = None,
- grid_gutter__istartswith: str | None = None,
- grid_gutter__endswith: str | None = None,
- grid_gutter__iendswith: str | None = None,
- grid_gutter__iexact: str | None = None,
- grid_gutter__in: list[str] | None = None,
- grid_gutter__isnull: bool | None = None,
- grid_maxWidth: str | None = None,
- grid_maxWidth__contains: str | None = None,
- grid_maxWidth__icontains: str | None = None,
- grid_maxWidth__startswith: str | None = None,
- grid_maxWidth__istartswith: str | None = None,
- grid_maxWidth__endswith: str | None = None,
- grid_maxWidth__iendswith: str | None = None,
- grid_maxWidth__iexact: str | None = None,
- grid_maxWidth__in: list[str] | None = None,
- grid_maxWidth__isnull: bool | None = None,
- id: int | None = None,
- id__gt: int | None = None,
- id__gte: int | None = None,
- id__lt: int | None = None,
- id__lte: int | None = None,
- id__between: tuple[int, int] | None = None,
- id__range: int | None = None,
- id__in: list[int] | None = None,
- id__isnull: bool | None = None,
- name: str | None = None,
- name__contains: str | None = None,
- name__icontains: str | None = None,
- name__startswith: str | None = None,
- name__istartswith: str | None = None,
- name__endswith: str | None = None,
- name__iendswith: str | None = None,
- name__iexact: str | None = None,
- name__in: list[str] | None = None,
- name__isnull: bool | None = None,
- ) -> "ThemeQuery":
- """Filter by Q-expressions or field lookups."""
- ...
-
- def exclude(
- self,
- *args: Any,
- bg_color: str | None = None,
- bg_color__contains: str | None = None,
- bg_color__icontains: str | None = None,
- bg_color__startswith: str | None = None,
- bg_color__istartswith: str | None = None,
- bg_color__endswith: str | None = None,
- bg_color__iendswith: str | None = None,
- bg_color__iexact: str | None = None,
- bg_color__in: list[str] | None = None,
- bg_color__isnull: bool | None = None,
- bg_secondary_color: str | None = None,
- bg_secondary_color__contains: str | None = None,
- bg_secondary_color__icontains: str | None = None,
- bg_secondary_color__startswith: str | None = None,
- bg_secondary_color__istartswith: str | None = None,
- bg_secondary_color__endswith: str | None = None,
- bg_secondary_color__iendswith: str | None = None,
- bg_secondary_color__iexact: str | None = None,
- bg_secondary_color__in: list[str] | None = None,
- bg_secondary_color__isnull: bool | None = None,
- color_darkGrey: str | None = None,
- color_darkGrey__contains: str | None = None,
- color_darkGrey__icontains: str | None = None,
- color_darkGrey__startswith: str | None = None,
- color_darkGrey__istartswith: str | None = None,
- color_darkGrey__endswith: str | None = None,
- color_darkGrey__iendswith: str | None = None,
- color_darkGrey__iexact: str | None = None,
- color_darkGrey__in: list[str] | None = None,
- color_darkGrey__isnull: bool | None = None,
- color_error: str | None = None,
- color_error__contains: str | None = None,
- color_error__icontains: str | None = None,
- color_error__startswith: str | None = None,
- color_error__istartswith: str | None = None,
- color_error__endswith: str | None = None,
- color_error__iendswith: str | None = None,
- color_error__iexact: str | None = None,
- color_error__in: list[str] | None = None,
- color_error__isnull: bool | None = None,
- color_grey: str | None = None,
- color_grey__contains: str | None = None,
- color_grey__icontains: str | None = None,
- color_grey__startswith: str | None = None,
- color_grey__istartswith: str | None = None,
- color_grey__endswith: str | None = None,
- color_grey__iendswith: str | None = None,
- color_grey__iexact: str | None = None,
- color_grey__in: list[str] | None = None,
- color_grey__isnull: bool | None = None,
- color_lightGrey: str | None = None,
- color_lightGrey__contains: str | None = None,
- color_lightGrey__icontains: str | None = None,
- color_lightGrey__startswith: str | None = None,
- color_lightGrey__istartswith: str | None = None,
- color_lightGrey__endswith: str | None = None,
- color_lightGrey__iendswith: str | None = None,
- color_lightGrey__iexact: str | None = None,
- color_lightGrey__in: list[str] | None = None,
- color_lightGrey__isnull: bool | None = None,
- color_primary: str | None = None,
- color_primary__contains: str | None = None,
- color_primary__icontains: str | None = None,
- color_primary__startswith: str | None = None,
- color_primary__istartswith: str | None = None,
- color_primary__endswith: str | None = None,
- color_primary__iendswith: str | None = None,
- color_primary__iexact: str | None = None,
- color_primary__in: list[str] | None = None,
- color_primary__isnull: bool | None = None,
- color_success: str | None = None,
- color_success__contains: str | None = None,
- color_success__icontains: str | None = None,
- color_success__startswith: str | None = None,
- color_success__istartswith: str | None = None,
- color_success__endswith: str | None = None,
- color_success__iendswith: str | None = None,
- color_success__iexact: str | None = None,
- color_success__in: list[str] | None = None,
- color_success__isnull: bool | None = None,
- font_color: str | None = None,
- font_color__contains: str | None = None,
- font_color__icontains: str | None = None,
- font_color__startswith: str | None = None,
- font_color__istartswith: str | None = None,
- font_color__endswith: str | None = None,
- font_color__iendswith: str | None = None,
- font_color__iexact: str | None = None,
- font_color__in: list[str] | None = None,
- font_color__isnull: bool | None = None,
- font_family_mono: str | None = None,
- font_family_mono__contains: str | None = None,
- font_family_mono__icontains: str | None = None,
- font_family_mono__startswith: str | None = None,
- font_family_mono__istartswith: str | None = None,
- font_family_mono__endswith: str | None = None,
- font_family_mono__iendswith: str | None = None,
- font_family_mono__iexact: str | None = None,
- font_family_mono__in: list[str] | None = None,
- font_family_mono__isnull: bool | None = None,
- font_family_sans: str | None = None,
- font_family_sans__contains: str | None = None,
- font_family_sans__icontains: str | None = None,
- font_family_sans__startswith: str | None = None,
- font_family_sans__istartswith: str | None = None,
- font_family_sans__endswith: str | None = None,
- font_family_sans__iendswith: str | None = None,
- font_family_sans__iexact: str | None = None,
- font_family_sans__in: list[str] | None = None,
- font_family_sans__isnull: bool | None = None,
- font_size: str | None = None,
- font_size__contains: str | None = None,
- font_size__icontains: str | None = None,
- font_size__startswith: str | None = None,
- font_size__istartswith: str | None = None,
- font_size__endswith: str | None = None,
- font_size__iendswith: str | None = None,
- font_size__iexact: str | None = None,
- font_size__in: list[str] | None = None,
- font_size__isnull: bool | None = None,
- grid_gutter: str | None = None,
- grid_gutter__contains: str | None = None,
- grid_gutter__icontains: str | None = None,
- grid_gutter__startswith: str | None = None,
- grid_gutter__istartswith: str | None = None,
- grid_gutter__endswith: str | None = None,
- grid_gutter__iendswith: str | None = None,
- grid_gutter__iexact: str | None = None,
- grid_gutter__in: list[str] | None = None,
- grid_gutter__isnull: bool | None = None,
- grid_maxWidth: str | None = None,
- grid_maxWidth__contains: str | None = None,
- grid_maxWidth__icontains: str | None = None,
- grid_maxWidth__startswith: str | None = None,
- grid_maxWidth__istartswith: str | None = None,
- grid_maxWidth__endswith: str | None = None,
- grid_maxWidth__iendswith: str | None = None,
- grid_maxWidth__iexact: str | None = None,
- grid_maxWidth__in: list[str] | None = None,
- grid_maxWidth__isnull: bool | None = None,
- id: int | None = None,
- id__gt: int | None = None,
- id__gte: int | None = None,
- id__lt: int | None = None,
- id__lte: int | None = None,
- id__between: tuple[int, int] | None = None,
- id__range: int | None = None,
- id__in: list[int] | None = None,
- id__isnull: bool | None = None,
- name: str | None = None,
- name__contains: str | None = None,
- name__icontains: str | None = None,
- name__startswith: str | None = None,
- name__istartswith: str | None = None,
- name__endswith: str | None = None,
- name__iendswith: str | None = None,
- name__iexact: str | None = None,
- name__in: list[str] | None = None,
- name__isnull: bool | None = None,
- ) -> "ThemeQuery":
- """Exclude objects matching field lookups."""
- ...
-
- def order_by(self, *fields: Literal["bg_color", "-bg_color", "bg_secondary_color", "-bg_secondary_color", "color_darkGrey", "-color_darkGrey", "color_error", "-color_error", "color_grey", "-color_grey", "color_lightGrey", "-color_lightGrey", "color_primary", "-color_primary", "color_success", "-color_success", "font_color", "-font_color", "font_family_mono", "-font_family_mono", "font_family_sans", "-font_family_sans", "font_size", "-font_size", "grid_gutter", "-grid_gutter", "grid_maxWidth", "-grid_maxWidth", "id", "-id", "name", "-name"]) -> "ThemeQuery": # type: ignore[override]
- """Order results by fields."""
- ...
-
- def limit(self, n: int) -> "ThemeQuery":
- """Limit number of results."""
- ...
-
- def offset(self, n: int) -> "ThemeQuery":
- """Skip first n results."""
- ...
-
- def distinct(self, value: bool = True) -> "ThemeQuery":
- """Return distinct results."""
- ...
-
- def select(self, *fields: Literal["bg_color", "bg_secondary_color", "color_darkGrey", "color_error", "color_grey", "color_lightGrey", "color_primary", "color_success", "font_color", "font_family_mono", "font_family_sans", "font_size", "grid_gutter", "grid_maxWidth", "id", "name"]) -> "ThemeQuery": # type: ignore[override]
- """Select specific fields."""
- ...
-
- def join(self, *paths: str) -> "ThemeQuery":
- """Perform LEFT JOIN for relations."""
- ...
-
- def prefetch(self, *paths: str) -> "ThemeQuery":
- """Prefetch related objects (separate queries)."""
- ...
-
- def for_update(self) -> "ThemeQuery":
- """Add FOR UPDATE lock to query."""
- ...
-
- def for_share(self) -> "ThemeQuery":
- """Add FOR SHARE lock to query."""
- ...
-
- def annotate(self, **annotations: Any) -> "ThemeQuery":
- """Add computed fields using aggregate functions."""
- ...
-
- def group_by(self, *fields: Literal["bg_color", "bg_secondary_color", "color_darkGrey", "color_error", "color_grey", "color_lightGrey", "color_primary", "color_success", "font_color", "font_family_mono", "font_family_sans", "font_size", "grid_gutter", "grid_maxWidth", "id", "name"]) -> "ThemeQuery": # type: ignore[override]
- """Add GROUP BY clause."""
- ...
-
- def having(self, *q_exprs: Any, **kwargs: Any) -> "ThemeQuery":
- """Add HAVING clause for filtering grouped results."""
- ...
-
- def values(self, *fields: Literal["bg_color", "bg_secondary_color", "color_darkGrey", "color_error", "color_grey", "color_lightGrey", "color_primary", "color_success", "font_color", "font_family_mono", "font_family_sans", "font_size", "grid_gutter", "grid_maxWidth", "id", "name"]) -> "ThemeQuery": # type: ignore[override]
- """Return dicts instead of models."""
- ...
-
- def values_list(self, *fields: Literal["bg_color", "bg_secondary_color", "color_darkGrey", "color_error", "color_grey", "color_lightGrey", "color_primary", "color_success", "font_color", "font_family_mono", "font_family_sans", "font_size", "grid_gutter", "grid_maxWidth", "id", "name"], flat: bool = False) -> "ThemeQuery": # type: ignore[override]
- """Return tuples/values instead of models."""
- ...
-
- # Terminal methods (async, execute query)
-
- async def all(
- self,
- *,
- client: Any | None = None,
- using: str | None = None,
- ) -> list[Theme]:
- """Execute query and return all results."""
- ...
-
- async def first(
- self,
- *,
- client: Any | None = None,
- using: str | None = None,
- ) -> Theme | None:
- """Execute query and return first result."""
- ...
-
- async def last(
- self,
- *,
- client: Any | None = None,
- using: str | None = None,
- ) -> Theme | None:
- """Execute query and return last result."""
- ...
-
- async def count(
- self,
- *,
- client: Any | None = None,
- using: str | None = None,
- ) -> int:
- """Count matching objects."""
- ...
-
- async def sum(
- self,
- field: str,
- *,
- client: Any | None = None,
- using: str | None = None,
- ) -> Any:
- """Calculate sum of field values."""
- ...
-
- async def avg(
- self,
- field: str,
- *,
- client: Any | None = None,
- using: str | None = None,
- ) -> Any:
- """Calculate average of field values."""
- ...
-
- async def max(
- self,
- field: str,
- *,
- client: Any | None = None,
- using: str | None = None,
- ) -> Any:
- """Get maximum field value."""
- ...
-
- async def min(
- self,
- field: str,
- *,
- client: Any | None = None,
- using: str | None = None,
- ) -> Any:
- """Get minimum field value."""
- ...
-
- async def update( # type: ignore[override]
- self,
- *,
- client: Any | None = None,
- using: str | None = None,
- **values: Any,
- ) -> int:
- """Update matching objects."""
- ...
-
- async def increment(
- self,
- field: str,
- by: int | float = 1,
- *,
- client: Any | None = None,
- using: str | None = None,
- ) -> int:
- """Atomically increment a field value."""
- ...
-
- async def delete(
- self,
- *,
- client: Any | None = None,
- using: str | None = None,
- ) -> int:
- """Delete matching objects."""
- ...
-
-class ThemeManager(QueryManager[Theme]):
- """Type-safe Manager for Theme model."""
-
- # Query building methods (sync, return Query)
-
- def query(self) -> ThemeQuery:
- """Return a Query builder for this model."""
- ...
-
- def filter(
- self,
- *args: Any,
- bg_color: str | None = None,
- bg_color__contains: str | None = None,
- bg_color__icontains: str | None = None,
- bg_color__startswith: str | None = None,
- bg_color__istartswith: str | None = None,
- bg_color__endswith: str | None = None,
- bg_color__iendswith: str | None = None,
- bg_color__iexact: str | None = None,
- bg_color__in: list[str] | None = None,
- bg_color__isnull: bool | None = None,
- bg_secondary_color: str | None = None,
- bg_secondary_color__contains: str | None = None,
- bg_secondary_color__icontains: str | None = None,
- bg_secondary_color__startswith: str | None = None,
- bg_secondary_color__istartswith: str | None = None,
- bg_secondary_color__endswith: str | None = None,
- bg_secondary_color__iendswith: str | None = None,
- bg_secondary_color__iexact: str | None = None,
- bg_secondary_color__in: list[str] | None = None,
- bg_secondary_color__isnull: bool | None = None,
- color_darkGrey: str | None = None,
- color_darkGrey__contains: str | None = None,
- color_darkGrey__icontains: str | None = None,
- color_darkGrey__startswith: str | None = None,
- color_darkGrey__istartswith: str | None = None,
- color_darkGrey__endswith: str | None = None,
- color_darkGrey__iendswith: str | None = None,
- color_darkGrey__iexact: str | None = None,
- color_darkGrey__in: list[str] | None = None,
- color_darkGrey__isnull: bool | None = None,
- color_error: str | None = None,
- color_error__contains: str | None = None,
- color_error__icontains: str | None = None,
- color_error__startswith: str | None = None,
- color_error__istartswith: str | None = None,
- color_error__endswith: str | None = None,
- color_error__iendswith: str | None = None,
- color_error__iexact: str | None = None,
- color_error__in: list[str] | None = None,
- color_error__isnull: bool | None = None,
- color_grey: str | None = None,
- color_grey__contains: str | None = None,
- color_grey__icontains: str | None = None,
- color_grey__startswith: str | None = None,
- color_grey__istartswith: str | None = None,
- color_grey__endswith: str | None = None,
- color_grey__iendswith: str | None = None,
- color_grey__iexact: str | None = None,
- color_grey__in: list[str] | None = None,
- color_grey__isnull: bool | None = None,
- color_lightGrey: str | None = None,
- color_lightGrey__contains: str | None = None,
- color_lightGrey__icontains: str | None = None,
- color_lightGrey__startswith: str | None = None,
- color_lightGrey__istartswith: str | None = None,
- color_lightGrey__endswith: str | None = None,
- color_lightGrey__iendswith: str | None = None,
- color_lightGrey__iexact: str | None = None,
- color_lightGrey__in: list[str] | None = None,
- color_lightGrey__isnull: bool | None = None,
- color_primary: str | None = None,
- color_primary__contains: str | None = None,
- color_primary__icontains: str | None = None,
- color_primary__startswith: str | None = None,
- color_primary__istartswith: str | None = None,
- color_primary__endswith: str | None = None,
- color_primary__iendswith: str | None = None,
- color_primary__iexact: str | None = None,
- color_primary__in: list[str] | None = None,
- color_primary__isnull: bool | None = None,
- color_success: str | None = None,
- color_success__contains: str | None = None,
- color_success__icontains: str | None = None,
- color_success__startswith: str | None = None,
- color_success__istartswith: str | None = None,
- color_success__endswith: str | None = None,
- color_success__iendswith: str | None = None,
- color_success__iexact: str | None = None,
- color_success__in: list[str] | None = None,
- color_success__isnull: bool | None = None,
- font_color: str | None = None,
- font_color__contains: str | None = None,
- font_color__icontains: str | None = None,
- font_color__startswith: str | None = None,
- font_color__istartswith: str | None = None,
- font_color__endswith: str | None = None,
- font_color__iendswith: str | None = None,
- font_color__iexact: str | None = None,
- font_color__in: list[str] | None = None,
- font_color__isnull: bool | None = None,
- font_family_mono: str | None = None,
- font_family_mono__contains: str | None = None,
- font_family_mono__icontains: str | None = None,
- font_family_mono__startswith: str | None = None,
- font_family_mono__istartswith: str | None = None,
- font_family_mono__endswith: str | None = None,
- font_family_mono__iendswith: str | None = None,
- font_family_mono__iexact: str | None = None,
- font_family_mono__in: list[str] | None = None,
- font_family_mono__isnull: bool | None = None,
- font_family_sans: str | None = None,
- font_family_sans__contains: str | None = None,
- font_family_sans__icontains: str | None = None,
- font_family_sans__startswith: str | None = None,
- font_family_sans__istartswith: str | None = None,
- font_family_sans__endswith: str | None = None,
- font_family_sans__iendswith: str | None = None,
- font_family_sans__iexact: str | None = None,
- font_family_sans__in: list[str] | None = None,
- font_family_sans__isnull: bool | None = None,
- font_size: str | None = None,
- font_size__contains: str | None = None,
- font_size__icontains: str | None = None,
- font_size__startswith: str | None = None,
- font_size__istartswith: str | None = None,
- font_size__endswith: str | None = None,
- font_size__iendswith: str | None = None,
- font_size__iexact: str | None = None,
- font_size__in: list[str] | None = None,
- font_size__isnull: bool | None = None,
- grid_gutter: str | None = None,
- grid_gutter__contains: str | None = None,
- grid_gutter__icontains: str | None = None,
- grid_gutter__startswith: str | None = None,
- grid_gutter__istartswith: str | None = None,
- grid_gutter__endswith: str | None = None,
- grid_gutter__iendswith: str | None = None,
- grid_gutter__iexact: str | None = None,
- grid_gutter__in: list[str] | None = None,
- grid_gutter__isnull: bool | None = None,
- grid_maxWidth: str | None = None,
- grid_maxWidth__contains: str | None = None,
- grid_maxWidth__icontains: str | None = None,
- grid_maxWidth__startswith: str | None = None,
- grid_maxWidth__istartswith: str | None = None,
- grid_maxWidth__endswith: str | None = None,
- grid_maxWidth__iendswith: str | None = None,
- grid_maxWidth__iexact: str | None = None,
- grid_maxWidth__in: list[str] | None = None,
- grid_maxWidth__isnull: bool | None = None,
- id: int | None = None,
- id__gt: int | None = None,
- id__gte: int | None = None,
- id__lt: int | None = None,
- id__lte: int | None = None,
- id__between: tuple[int, int] | None = None,
- id__range: int | None = None,
- id__in: list[int] | None = None,
- id__isnull: bool | None = None,
- name: str | None = None,
- name__contains: str | None = None,
- name__icontains: str | None = None,
- name__startswith: str | None = None,
- name__istartswith: str | None = None,
- name__endswith: str | None = None,
- name__iendswith: str | None = None,
- name__iexact: str | None = None,
- name__in: list[str] | None = None,
- name__isnull: bool | None = None,
- ) -> ThemeQuery:
- """Filter by Q-expressions or field lookups."""
- ...
-
- def exclude(
- self,
- *args: Any,
- bg_color: str | None = None,
- bg_color__contains: str | None = None,
- bg_color__icontains: str | None = None,
- bg_color__startswith: str | None = None,
- bg_color__istartswith: str | None = None,
- bg_color__endswith: str | None = None,
- bg_color__iendswith: str | None = None,
- bg_color__iexact: str | None = None,
- bg_color__in: list[str] | None = None,
- bg_color__isnull: bool | None = None,
- bg_secondary_color: str | None = None,
- bg_secondary_color__contains: str | None = None,
- bg_secondary_color__icontains: str | None = None,
- bg_secondary_color__startswith: str | None = None,
- bg_secondary_color__istartswith: str | None = None,
- bg_secondary_color__endswith: str | None = None,
- bg_secondary_color__iendswith: str | None = None,
- bg_secondary_color__iexact: str | None = None,
- bg_secondary_color__in: list[str] | None = None,
- bg_secondary_color__isnull: bool | None = None,
- color_darkGrey: str | None = None,
- color_darkGrey__contains: str | None = None,
- color_darkGrey__icontains: str | None = None,
- color_darkGrey__startswith: str | None = None,
- color_darkGrey__istartswith: str | None = None,
- color_darkGrey__endswith: str | None = None,
- color_darkGrey__iendswith: str | None = None,
- color_darkGrey__iexact: str | None = None,
- color_darkGrey__in: list[str] | None = None,
- color_darkGrey__isnull: bool | None = None,
- color_error: str | None = None,
- color_error__contains: str | None = None,
- color_error__icontains: str | None = None,
- color_error__startswith: str | None = None,
- color_error__istartswith: str | None = None,
- color_error__endswith: str | None = None,
- color_error__iendswith: str | None = None,
- color_error__iexact: str | None = None,
- color_error__in: list[str] | None = None,
- color_error__isnull: bool | None = None,
- color_grey: str | None = None,
- color_grey__contains: str | None = None,
- color_grey__icontains: str | None = None,
- color_grey__startswith: str | None = None,
- color_grey__istartswith: str | None = None,
- color_grey__endswith: str | None = None,
- color_grey__iendswith: str | None = None,
- color_grey__iexact: str | None = None,
- color_grey__in: list[str] | None = None,
- color_grey__isnull: bool | None = None,
- color_lightGrey: str | None = None,
- color_lightGrey__contains: str | None = None,
- color_lightGrey__icontains: str | None = None,
- color_lightGrey__startswith: str | None = None,
- color_lightGrey__istartswith: str | None = None,
- color_lightGrey__endswith: str | None = None,
- color_lightGrey__iendswith: str | None = None,
- color_lightGrey__iexact: str | None = None,
- color_lightGrey__in: list[str] | None = None,
- color_lightGrey__isnull: bool | None = None,
- color_primary: str | None = None,
- color_primary__contains: str | None = None,
- color_primary__icontains: str | None = None,
- color_primary__startswith: str | None = None,
- color_primary__istartswith: str | None = None,
- color_primary__endswith: str | None = None,
- color_primary__iendswith: str | None = None,
- color_primary__iexact: str | None = None,
- color_primary__in: list[str] | None = None,
- color_primary__isnull: bool | None = None,
- color_success: str | None = None,
- color_success__contains: str | None = None,
- color_success__icontains: str | None = None,
- color_success__startswith: str | None = None,
- color_success__istartswith: str | None = None,
- color_success__endswith: str | None = None,
- color_success__iendswith: str | None = None,
- color_success__iexact: str | None = None,
- color_success__in: list[str] | None = None,
- color_success__isnull: bool | None = None,
- font_color: str | None = None,
- font_color__contains: str | None = None,
- font_color__icontains: str | None = None,
- font_color__startswith: str | None = None,
- font_color__istartswith: str | None = None,
- font_color__endswith: str | None = None,
- font_color__iendswith: str | None = None,
- font_color__iexact: str | None = None,
- font_color__in: list[str] | None = None,
- font_color__isnull: bool | None = None,
- font_family_mono: str | None = None,
- font_family_mono__contains: str | None = None,
- font_family_mono__icontains: str | None = None,
- font_family_mono__startswith: str | None = None,
- font_family_mono__istartswith: str | None = None,
- font_family_mono__endswith: str | None = None,
- font_family_mono__iendswith: str | None = None,
- font_family_mono__iexact: str | None = None,
- font_family_mono__in: list[str] | None = None,
- font_family_mono__isnull: bool | None = None,
- font_family_sans: str | None = None,
- font_family_sans__contains: str | None = None,
- font_family_sans__icontains: str | None = None,
- font_family_sans__startswith: str | None = None,
- font_family_sans__istartswith: str | None = None,
- font_family_sans__endswith: str | None = None,
- font_family_sans__iendswith: str | None = None,
- font_family_sans__iexact: str | None = None,
- font_family_sans__in: list[str] | None = None,
- font_family_sans__isnull: bool | None = None,
- font_size: str | None = None,
- font_size__contains: str | None = None,
- font_size__icontains: str | None = None,
- font_size__startswith: str | None = None,
- font_size__istartswith: str | None = None,
- font_size__endswith: str | None = None,
- font_size__iendswith: str | None = None,
- font_size__iexact: str | None = None,
- font_size__in: list[str] | None = None,
- font_size__isnull: bool | None = None,
- grid_gutter: str | None = None,
- grid_gutter__contains: str | None = None,
- grid_gutter__icontains: str | None = None,
- grid_gutter__startswith: str | None = None,
- grid_gutter__istartswith: str | None = None,
- grid_gutter__endswith: str | None = None,
- grid_gutter__iendswith: str | None = None,
- grid_gutter__iexact: str | None = None,
- grid_gutter__in: list[str] | None = None,
- grid_gutter__isnull: bool | None = None,
- grid_maxWidth: str | None = None,
- grid_maxWidth__contains: str | None = None,
- grid_maxWidth__icontains: str | None = None,
- grid_maxWidth__startswith: str | None = None,
- grid_maxWidth__istartswith: str | None = None,
- grid_maxWidth__endswith: str | None = None,
- grid_maxWidth__iendswith: str | None = None,
- grid_maxWidth__iexact: str | None = None,
- grid_maxWidth__in: list[str] | None = None,
- grid_maxWidth__isnull: bool | None = None,
- id: int | None = None,
- id__gt: int | None = None,
- id__gte: int | None = None,
- id__lt: int | None = None,
- id__lte: int | None = None,
- id__between: tuple[int, int] | None = None,
- id__range: int | None = None,
- id__in: list[int] | None = None,
- id__isnull: bool | None = None,
- name: str | None = None,
- name__contains: str | None = None,
- name__icontains: str | None = None,
- name__startswith: str | None = None,
- name__istartswith: str | None = None,
- name__endswith: str | None = None,
- name__iendswith: str | None = None,
- name__iexact: str | None = None,
- name__in: list[str] | None = None,
- name__isnull: bool | None = None,
- ) -> ThemeQuery:
- """Exclude objects matching field lookups."""
- ...
-
- def values(self, *fields: Literal["bg_color", "bg_secondary_color", "color_darkGrey", "color_error", "color_grey", "color_lightGrey", "color_primary", "color_success", "font_color", "font_family_mono", "font_family_sans", "font_size", "grid_gutter", "grid_maxWidth", "id", "name"]) -> ThemeQuery: # type: ignore[override]
- """Return dicts instead of models."""
- ...
-
- def values_list(self, *fields: Literal["bg_color", "bg_secondary_color", "color_darkGrey", "color_error", "color_grey", "color_lightGrey", "color_primary", "color_success", "font_color", "font_family_mono", "font_family_sans", "font_size", "grid_gutter", "grid_maxWidth", "id", "name"], flat: bool = False) -> ThemeQuery: # type: ignore[override]
- """Return tuples/values instead of models."""
- ...
-
- def distinct(self, distinct: bool = True) -> ThemeQuery:
- """Return distinct results."""
- ...
-
- def join(self, *paths: str) -> ThemeQuery:
- """Perform LEFT JOIN for relations."""
- ...
-
- def prefetch(self, *paths: str) -> ThemeQuery:
- """Prefetch related objects (separate queries)."""
- ...
-
- def for_update(self) -> ThemeQuery:
- """Add FOR UPDATE lock to query."""
- ...
-
- def for_share(self) -> ThemeQuery:
- """Add FOR SHARE lock to query."""
- ...
-
- # Terminal methods (async, execute query)
-
- async def get(
- self,
- *,
- client: Any | None = None,
- using: str | None = None,
- **filters: Any,
- ) -> Theme:
- """Get single object matching lookups."""
- ...
-
- async def get_or_none(
- self,
- *,
- client: Any | None = None,
- using: str | None = None,
- **filters: Any,
- ) -> Theme | None:
- """Get object or None if not found."""
- ...
-
- async def get_or_create(
- self,
- *,
- defaults: dict[str, Any] | None = None,
- client: Any | None = None,
- using: str | None = None,
- **filters: Any,
- ) -> tuple[Theme, bool]:
- """Get object or create if not found. Returns (object, created)."""
- ...
-
- async def update_or_create(
- self,
- *,
- defaults: dict[str, Any] | None = None,
- client: Any | None = None,
- using: str | None = None,
- **filters: Any,
- ) -> tuple[Theme, bool]:
- """Get object, create if missing, or update it when defaults are provided."""
- ...
-
- async def all(
- self,
- *,
- client: Any | None = None,
- using: str | None = None,
- mode: str = "models",
- ) -> list[Theme]:
- """Get all objects."""
- ...
-
- async def first(
- self,
- *,
- client: Any | None = None,
- using: str | None = None,
- ) -> Theme | None:
- """Get first object."""
- ...
-
- async def last(
- self,
- *,
- client: Any | None = None,
- using: str | None = None,
- ) -> Theme | None:
- """Get last object."""
- ...
-
- async def count(
- self,
- *,
- client: Any | None = None,
- using: str | None = None,
- ) -> int:
- """Count all objects."""
- ...
-
- async def sum(
- self,
- field: str,
- *,
- client: Any | None = None,
- using: str | None = None,
- ) -> Any:
- """Calculate sum of field values."""
- ...
-
- async def avg(
- self,
- field: str,
- *,
- client: Any | None = None,
- using: str | None = None,
- ) -> Any:
- """Calculate average of field values."""
- ...
-
- async def max(
- self,
- field: str,
- *,
- client: Any | None = None,
- using: str | None = None,
- ) -> Any:
- """Get maximum field value."""
- ...
-
- async def min(
- self,
- field: str,
- *,
- client: Any | None = None,
- using: str | None = None,
- ) -> Any:
- """Get minimum field value."""
- ...
-
- async def create( # type: ignore[override]
- self,
- *,
- instance: Theme | None = None,
- client: Any | None = None,
- using: str | None = None,
- bg_color: str | None = None,
- bg_secondary_color: str | None = None,
- color_darkGrey: str | None = None,
- color_error: str | None = None,
- color_grey: str | None = None,
- color_lightGrey: str | None = None,
- color_primary: str | None = None,
- color_success: str | None = None,
- font_color: str | None = None,
- font_family_mono: str | None = None,
- font_family_sans: str | None = None,
- font_size: str | None = None,
- grid_gutter: str | None = None,
- grid_maxWidth: str | None = None,
- id: int | None = None,
- name: str | None = None,
- ) -> Theme:
- """Create new object."""
- ...
-
- async def bulk_create( # type: ignore[override]
- self,
- objects: list[Theme],
- *,
- batch_size: int | None = None,
- client: Any | None = None,
- using: str | None = None,
- ) -> list[Theme]:
- """Bulk create objects."""
- ...
-
- async def bulk_update( # type: ignore[override]
- self,
- objects: list[Theme],
- fields: list[str],
- *,
- client: Any | None = None,
- using: str | None = None,
- ) -> int:
- """Bulk update objects."""
- ...
-
diff --git a/freenit/models/sql/blog.py b/freenit/models/sql/blog.py
new file mode 100644
index 0000000..217f5a6
--- /dev/null
+++ b/freenit/models/sql/blog.py
@@ -0,0 +1,68 @@
+from __future__ import annotations
+
+from datetime import datetime
+
+import oxyde
+import pydantic
+
+from freenit.models.sql.base import OxydeBaseModel, User
+
+NotFoundError = oxyde.NotFoundError
+IntegrityError = oxyde.IntegrityError
+
+
+class Tag(OxydeBaseModel):
+ id: int | None = oxyde.Field(default=None, db_pk=True)
+ name: str = oxyde.Field(db_unique=True, db_index=True)
+
+ class Meta:
+ is_table = True
+ table_name = "blog_tag"
+
+
+class BlogPost(OxydeBaseModel):
+ id: int | None = oxyde.Field(default=None, db_pk=True)
+ title: str = oxyde.Field()
+ slug: str = oxyde.Field(db_unique=True, db_index=True)
+ content: str = oxyde.Field()
+ date: datetime | None = oxyde.Field(default=None)
+ author: User | None = oxyde.Field(default=None, db_fk="id", db_on_delete="SET NULL")
+ published: bool = oxyde.Field(default=False)
+ tags: list[Tag] = oxyde.Field(
+ default_factory=list, db_m2m=True, db_through="BlogPostTag"
+ )
+ created_at: datetime | None = oxyde.Field(default=None)
+ updated_at: datetime | None = oxyde.Field(default=None)
+
+ class Meta:
+ is_table = True
+ table_name = "blog_post"
+
+
+class BlogPostTag(OxydeBaseModel):
+ id: int | None = oxyde.Field(default=None, db_pk=True)
+ post: BlogPost | None = oxyde.Field(
+ default=None, db_fk="id", db_on_delete="CASCADE"
+ )
+ tag: Tag | None = oxyde.Field(default=None, db_fk="id", db_on_delete="CASCADE")
+
+ class Meta:
+ is_table = True
+ table_name = "blog_post_tag"
+ unique_together = [("post_id", "tag_id")]
+
+
+class BlogPostOptional(pydantic.BaseModel):
+ model_config = pydantic.ConfigDict(extra="forbid")
+
+ title: str | None = None
+ slug: str | None = None
+ content: str | None = None
+ date: datetime | None = None
+ published: bool | None = None
+ tags: list[str] | None = None
+
+
+BlogPost.model_rebuild()
+Tag.model_rebuild()
+BlogPostTag.model_rebuild()
diff --git a/freenit/models/sql/git.py b/freenit/models/sql/git.py
index d07d8bf..d91475d 100644
--- a/freenit/models/sql/git.py
+++ b/freenit/models/sql/git.py
@@ -23,6 +23,7 @@ class GitRepo(OxydeBaseModel):
default_branch: str = oxyde.Field(default="main")
tests_enabled: bool = oxyde.Field(default=False)
test_command: str | None = oxyde.Field(default=None)
+ webhook_url: str | None = oxyde.Field(default=None)
created_at: datetime | None = oxyde.Field(default=None)
updated_at: datetime | None = oxyde.Field(default=None)
diff --git a/freenit/models/sql/git.pyi b/freenit/models/sql/git.pyi
new file mode 100644
index 0000000..fbe7331
--- /dev/null
+++ b/freenit/models/sql/git.pyi
@@ -0,0 +1,2994 @@
+# Auto-generated by oxyde generate-stubs
+# DO NOT EDIT - This file will be overwritten
+
+from typing import Any, ClassVar, Literal
+from datetime import datetime, date, time
+from decimal import Decimal
+from uuid import UUID
+
+from oxyde import Model
+from oxyde.queries import Query, QueryManager
+
+from __future__ import annotations
+from datetime import datetime
+import oxyde
+from freenit.models.project import Project
+from freenit.models.sql.base import OxydeBaseModel
+
+class GitRepo(Model):
+ class Meta:
+ is_table: bool
+ table_name: str
+ id: int | None
+ project: Project | None
+ name: str
+ path: str
+ description: str | None
+ public: bool
+ default_branch: str
+ tests_enabled: bool
+ test_command: str | None
+ webhook_url: str | None
+ created_at: datetime | None
+ updated_at: datetime | None
+ project_id: int | None
+ objects: ClassVar["GitRepoManager"]
+
+
+class GitRepoQuery(Query[GitRepo]):
+ """Type-safe Query for GitRepo model."""
+
+ # Query building methods (sync, return Query)
+
+ def filter(
+ self,
+ *args: Any,
+ created_at: datetime | None = None,
+ created_at__gt: datetime | None = None,
+ created_at__gte: datetime | None = None,
+ created_at__lt: datetime | None = None,
+ created_at__lte: datetime | None = None,
+ created_at__between: tuple[datetime, datetime] | None = None,
+ created_at__range: datetime | None = None,
+ created_at__year: int | None = None,
+ created_at__month: int | None = None,
+ created_at__day: int | None = None,
+ created_at__in: list[datetime] | None = None,
+ created_at__isnull: bool | None = None,
+ default_branch: str | None = None,
+ default_branch__contains: str | None = None,
+ default_branch__icontains: str | None = None,
+ default_branch__startswith: str | None = None,
+ default_branch__istartswith: str | None = None,
+ default_branch__endswith: str | None = None,
+ default_branch__iendswith: str | None = None,
+ default_branch__iexact: str | None = None,
+ default_branch__in: list[str] | None = None,
+ default_branch__isnull: bool | None = None,
+ description: str | None = None,
+ description__contains: str | None = None,
+ description__icontains: str | None = None,
+ description__startswith: str | None = None,
+ description__istartswith: str | None = None,
+ description__endswith: str | None = None,
+ description__iendswith: str | None = None,
+ description__iexact: str | None = None,
+ description__in: list[str] | None = None,
+ description__isnull: bool | None = None,
+ id: int | None = None,
+ id__gt: int | None = None,
+ id__gte: int | None = None,
+ id__lt: int | None = None,
+ id__lte: int | None = None,
+ id__between: tuple[int, int] | None = None,
+ id__range: int | None = None,
+ id__in: list[int] | None = None,
+ id__isnull: bool | None = None,
+ name: str | None = None,
+ name__contains: str | None = None,
+ name__icontains: str | None = None,
+ name__startswith: str | None = None,
+ name__istartswith: str | None = None,
+ name__endswith: str | None = None,
+ name__iendswith: str | None = None,
+ name__iexact: str | None = None,
+ name__in: list[str] | None = None,
+ name__isnull: bool | None = None,
+ path: str | None = None,
+ path__contains: str | None = None,
+ path__icontains: str | None = None,
+ path__startswith: str | None = None,
+ path__istartswith: str | None = None,
+ path__endswith: str | None = None,
+ path__iendswith: str | None = None,
+ path__iexact: str | None = None,
+ path__in: list[str] | None = None,
+ path__isnull: bool | None = None,
+ project: Project | None = None,
+ project__in: list[Project] | None = None,
+ project__isnull: bool | None = None,
+ project_id: int | None = None,
+ project_id__gt: int | None = None,
+ project_id__gte: int | None = None,
+ project_id__lt: int | None = None,
+ project_id__lte: int | None = None,
+ project_id__between: tuple[int, int] | None = None,
+ project_id__range: int | None = None,
+ project_id__in: list[int] | None = None,
+ project_id__isnull: bool | None = None,
+ public: bool | None = None,
+ public__in: list[bool] | None = None,
+ public__isnull: bool | None = None,
+ test_command: str | None = None,
+ test_command__contains: str | None = None,
+ test_command__icontains: str | None = None,
+ test_command__startswith: str | None = None,
+ test_command__istartswith: str | None = None,
+ test_command__endswith: str | None = None,
+ test_command__iendswith: str | None = None,
+ test_command__iexact: str | None = None,
+ test_command__in: list[str] | None = None,
+ test_command__isnull: bool | None = None,
+ tests_enabled: bool | None = None,
+ tests_enabled__in: list[bool] | None = None,
+ tests_enabled__isnull: bool | None = None,
+ updated_at: datetime | None = None,
+ updated_at__gt: datetime | None = None,
+ updated_at__gte: datetime | None = None,
+ updated_at__lt: datetime | None = None,
+ updated_at__lte: datetime | None = None,
+ updated_at__between: tuple[datetime, datetime] | None = None,
+ updated_at__range: datetime | None = None,
+ updated_at__year: int | None = None,
+ updated_at__month: int | None = None,
+ updated_at__day: int | None = None,
+ updated_at__in: list[datetime] | None = None,
+ updated_at__isnull: bool | None = None,
+ webhook_url: str | None = None,
+ webhook_url__contains: str | None = None,
+ webhook_url__icontains: str | None = None,
+ webhook_url__startswith: str | None = None,
+ webhook_url__istartswith: str | None = None,
+ webhook_url__endswith: str | None = None,
+ webhook_url__iendswith: str | None = None,
+ webhook_url__iexact: str | None = None,
+ webhook_url__in: list[str] | None = None,
+ webhook_url__isnull: bool | None = None,
+ ) -> "GitRepoQuery":
+ """Filter by Q-expressions or field lookups."""
+ ...
+
+ def exclude(
+ self,
+ *args: Any,
+ created_at: datetime | None = None,
+ created_at__gt: datetime | None = None,
+ created_at__gte: datetime | None = None,
+ created_at__lt: datetime | None = None,
+ created_at__lte: datetime | None = None,
+ created_at__between: tuple[datetime, datetime] | None = None,
+ created_at__range: datetime | None = None,
+ created_at__year: int | None = None,
+ created_at__month: int | None = None,
+ created_at__day: int | None = None,
+ created_at__in: list[datetime] | None = None,
+ created_at__isnull: bool | None = None,
+ default_branch: str | None = None,
+ default_branch__contains: str | None = None,
+ default_branch__icontains: str | None = None,
+ default_branch__startswith: str | None = None,
+ default_branch__istartswith: str | None = None,
+ default_branch__endswith: str | None = None,
+ default_branch__iendswith: str | None = None,
+ default_branch__iexact: str | None = None,
+ default_branch__in: list[str] | None = None,
+ default_branch__isnull: bool | None = None,
+ description: str | None = None,
+ description__contains: str | None = None,
+ description__icontains: str | None = None,
+ description__startswith: str | None = None,
+ description__istartswith: str | None = None,
+ description__endswith: str | None = None,
+ description__iendswith: str | None = None,
+ description__iexact: str | None = None,
+ description__in: list[str] | None = None,
+ description__isnull: bool | None = None,
+ id: int | None = None,
+ id__gt: int | None = None,
+ id__gte: int | None = None,
+ id__lt: int | None = None,
+ id__lte: int | None = None,
+ id__between: tuple[int, int] | None = None,
+ id__range: int | None = None,
+ id__in: list[int] | None = None,
+ id__isnull: bool | None = None,
+ name: str | None = None,
+ name__contains: str | None = None,
+ name__icontains: str | None = None,
+ name__startswith: str | None = None,
+ name__istartswith: str | None = None,
+ name__endswith: str | None = None,
+ name__iendswith: str | None = None,
+ name__iexact: str | None = None,
+ name__in: list[str] | None = None,
+ name__isnull: bool | None = None,
+ path: str | None = None,
+ path__contains: str | None = None,
+ path__icontains: str | None = None,
+ path__startswith: str | None = None,
+ path__istartswith: str | None = None,
+ path__endswith: str | None = None,
+ path__iendswith: str | None = None,
+ path__iexact: str | None = None,
+ path__in: list[str] | None = None,
+ path__isnull: bool | None = None,
+ project: Project | None = None,
+ project__in: list[Project] | None = None,
+ project__isnull: bool | None = None,
+ project_id: int | None = None,
+ project_id__gt: int | None = None,
+ project_id__gte: int | None = None,
+ project_id__lt: int | None = None,
+ project_id__lte: int | None = None,
+ project_id__between: tuple[int, int] | None = None,
+ project_id__range: int | None = None,
+ project_id__in: list[int] | None = None,
+ project_id__isnull: bool | None = None,
+ public: bool | None = None,
+ public__in: list[bool] | None = None,
+ public__isnull: bool | None = None,
+ test_command: str | None = None,
+ test_command__contains: str | None = None,
+ test_command__icontains: str | None = None,
+ test_command__startswith: str | None = None,
+ test_command__istartswith: str | None = None,
+ test_command__endswith: str | None = None,
+ test_command__iendswith: str | None = None,
+ test_command__iexact: str | None = None,
+ test_command__in: list[str] | None = None,
+ test_command__isnull: bool | None = None,
+ tests_enabled: bool | None = None,
+ tests_enabled__in: list[bool] | None = None,
+ tests_enabled__isnull: bool | None = None,
+ updated_at: datetime | None = None,
+ updated_at__gt: datetime | None = None,
+ updated_at__gte: datetime | None = None,
+ updated_at__lt: datetime | None = None,
+ updated_at__lte: datetime | None = None,
+ updated_at__between: tuple[datetime, datetime] | None = None,
+ updated_at__range: datetime | None = None,
+ updated_at__year: int | None = None,
+ updated_at__month: int | None = None,
+ updated_at__day: int | None = None,
+ updated_at__in: list[datetime] | None = None,
+ updated_at__isnull: bool | None = None,
+ webhook_url: str | None = None,
+ webhook_url__contains: str | None = None,
+ webhook_url__icontains: str | None = None,
+ webhook_url__startswith: str | None = None,
+ webhook_url__istartswith: str | None = None,
+ webhook_url__endswith: str | None = None,
+ webhook_url__iendswith: str | None = None,
+ webhook_url__iexact: str | None = None,
+ webhook_url__in: list[str] | None = None,
+ webhook_url__isnull: bool | None = None,
+ ) -> "GitRepoQuery":
+ """Exclude objects matching field lookups."""
+ ...
+
+ def order_by(self, *fields: Literal["created_at", "-created_at", "default_branch", "-default_branch", "description", "-description", "id", "-id", "name", "-name", "path", "-path", "project", "-project", "project_id", "-project_id", "public", "-public", "test_command", "-test_command", "tests_enabled", "-tests_enabled", "updated_at", "-updated_at", "webhook_url", "-webhook_url"]) -> "GitRepoQuery": # type: ignore[override]
+ """Order results by fields."""
+ ...
+
+ def limit(self, n: int) -> "GitRepoQuery":
+ """Limit number of results."""
+ ...
+
+ def offset(self, n: int) -> "GitRepoQuery":
+ """Skip first n results."""
+ ...
+
+ def distinct(self, value: bool = True) -> "GitRepoQuery":
+ """Return distinct results."""
+ ...
+
+ def select(self, *fields: Literal["created_at", "default_branch", "description", "id", "name", "path", "project", "project_id", "public", "test_command", "tests_enabled", "updated_at", "webhook_url"]) -> "GitRepoQuery": # type: ignore[override]
+ """Select specific fields."""
+ ...
+
+ def join(self, *paths: str) -> "GitRepoQuery":
+ """Perform LEFT JOIN for relations."""
+ ...
+
+ def prefetch(self, *paths: str) -> "GitRepoQuery":
+ """Prefetch related objects (separate queries)."""
+ ...
+
+ def for_update(self) -> "GitRepoQuery":
+ """Add FOR UPDATE lock to query."""
+ ...
+
+ def for_share(self) -> "GitRepoQuery":
+ """Add FOR SHARE lock to query."""
+ ...
+
+ def annotate(self, **annotations: Any) -> "GitRepoQuery":
+ """Add computed fields using aggregate functions."""
+ ...
+
+ def group_by(self, *fields: Literal["created_at", "default_branch", "description", "id", "name", "path", "project", "project_id", "public", "test_command", "tests_enabled", "updated_at", "webhook_url"]) -> "GitRepoQuery": # type: ignore[override]
+ """Add GROUP BY clause."""
+ ...
+
+ def having(self, *q_exprs: Any, **kwargs: Any) -> "GitRepoQuery":
+ """Add HAVING clause for filtering grouped results."""
+ ...
+
+ def values(self, *fields: Literal["created_at", "default_branch", "description", "id", "name", "path", "project", "project_id", "public", "test_command", "tests_enabled", "updated_at", "webhook_url"]) -> "GitRepoQuery": # type: ignore[override]
+ """Return dicts instead of models."""
+ ...
+
+ def values_list(self, *fields: Literal["created_at", "default_branch", "description", "id", "name", "path", "project", "project_id", "public", "test_command", "tests_enabled", "updated_at", "webhook_url"], flat: bool = False) -> "GitRepoQuery": # type: ignore[override]
+ """Return tuples/values instead of models."""
+ ...
+
+ # Terminal methods (async, execute query)
+
+ async def all(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> list[GitRepo]:
+ """Execute query and return all results."""
+ ...
+
+ async def first(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> GitRepo | None:
+ """Execute query and return first result."""
+ ...
+
+ async def last(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> GitRepo | None:
+ """Execute query and return last result."""
+ ...
+
+ async def count(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> int:
+ """Count matching objects."""
+ ...
+
+ async def sum(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Calculate sum of field values."""
+ ...
+
+ async def avg(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Calculate average of field values."""
+ ...
+
+ async def max(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Get maximum field value."""
+ ...
+
+ async def min(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Get minimum field value."""
+ ...
+
+ async def update( # type: ignore[override]
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ **values: Any,
+ ) -> int:
+ """Update matching objects."""
+ ...
+
+ async def increment(
+ self,
+ field: str,
+ by: int | float = 1,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> int:
+ """Atomically increment a field value."""
+ ...
+
+ async def delete(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> int:
+ """Delete matching objects."""
+ ...
+
+class GitRepoManager(QueryManager[GitRepo]):
+ """Type-safe Manager for GitRepo model."""
+
+ # Query building methods (sync, return Query)
+
+ def query(self) -> GitRepoQuery:
+ """Return a Query builder for this model."""
+ ...
+
+ def filter(
+ self,
+ *args: Any,
+ created_at: datetime | None = None,
+ created_at__gt: datetime | None = None,
+ created_at__gte: datetime | None = None,
+ created_at__lt: datetime | None = None,
+ created_at__lte: datetime | None = None,
+ created_at__between: tuple[datetime, datetime] | None = None,
+ created_at__range: datetime | None = None,
+ created_at__year: int | None = None,
+ created_at__month: int | None = None,
+ created_at__day: int | None = None,
+ created_at__in: list[datetime] | None = None,
+ created_at__isnull: bool | None = None,
+ default_branch: str | None = None,
+ default_branch__contains: str | None = None,
+ default_branch__icontains: str | None = None,
+ default_branch__startswith: str | None = None,
+ default_branch__istartswith: str | None = None,
+ default_branch__endswith: str | None = None,
+ default_branch__iendswith: str | None = None,
+ default_branch__iexact: str | None = None,
+ default_branch__in: list[str] | None = None,
+ default_branch__isnull: bool | None = None,
+ description: str | None = None,
+ description__contains: str | None = None,
+ description__icontains: str | None = None,
+ description__startswith: str | None = None,
+ description__istartswith: str | None = None,
+ description__endswith: str | None = None,
+ description__iendswith: str | None = None,
+ description__iexact: str | None = None,
+ description__in: list[str] | None = None,
+ description__isnull: bool | None = None,
+ id: int | None = None,
+ id__gt: int | None = None,
+ id__gte: int | None = None,
+ id__lt: int | None = None,
+ id__lte: int | None = None,
+ id__between: tuple[int, int] | None = None,
+ id__range: int | None = None,
+ id__in: list[int] | None = None,
+ id__isnull: bool | None = None,
+ name: str | None = None,
+ name__contains: str | None = None,
+ name__icontains: str | None = None,
+ name__startswith: str | None = None,
+ name__istartswith: str | None = None,
+ name__endswith: str | None = None,
+ name__iendswith: str | None = None,
+ name__iexact: str | None = None,
+ name__in: list[str] | None = None,
+ name__isnull: bool | None = None,
+ path: str | None = None,
+ path__contains: str | None = None,
+ path__icontains: str | None = None,
+ path__startswith: str | None = None,
+ path__istartswith: str | None = None,
+ path__endswith: str | None = None,
+ path__iendswith: str | None = None,
+ path__iexact: str | None = None,
+ path__in: list[str] | None = None,
+ path__isnull: bool | None = None,
+ project: Project | None = None,
+ project__in: list[Project] | None = None,
+ project__isnull: bool | None = None,
+ project_id: int | None = None,
+ project_id__gt: int | None = None,
+ project_id__gte: int | None = None,
+ project_id__lt: int | None = None,
+ project_id__lte: int | None = None,
+ project_id__between: tuple[int, int] | None = None,
+ project_id__range: int | None = None,
+ project_id__in: list[int] | None = None,
+ project_id__isnull: bool | None = None,
+ public: bool | None = None,
+ public__in: list[bool] | None = None,
+ public__isnull: bool | None = None,
+ test_command: str | None = None,
+ test_command__contains: str | None = None,
+ test_command__icontains: str | None = None,
+ test_command__startswith: str | None = None,
+ test_command__istartswith: str | None = None,
+ test_command__endswith: str | None = None,
+ test_command__iendswith: str | None = None,
+ test_command__iexact: str | None = None,
+ test_command__in: list[str] | None = None,
+ test_command__isnull: bool | None = None,
+ tests_enabled: bool | None = None,
+ tests_enabled__in: list[bool] | None = None,
+ tests_enabled__isnull: bool | None = None,
+ updated_at: datetime | None = None,
+ updated_at__gt: datetime | None = None,
+ updated_at__gte: datetime | None = None,
+ updated_at__lt: datetime | None = None,
+ updated_at__lte: datetime | None = None,
+ updated_at__between: tuple[datetime, datetime] | None = None,
+ updated_at__range: datetime | None = None,
+ updated_at__year: int | None = None,
+ updated_at__month: int | None = None,
+ updated_at__day: int | None = None,
+ updated_at__in: list[datetime] | None = None,
+ updated_at__isnull: bool | None = None,
+ webhook_url: str | None = None,
+ webhook_url__contains: str | None = None,
+ webhook_url__icontains: str | None = None,
+ webhook_url__startswith: str | None = None,
+ webhook_url__istartswith: str | None = None,
+ webhook_url__endswith: str | None = None,
+ webhook_url__iendswith: str | None = None,
+ webhook_url__iexact: str | None = None,
+ webhook_url__in: list[str] | None = None,
+ webhook_url__isnull: bool | None = None,
+ ) -> GitRepoQuery:
+ """Filter by Q-expressions or field lookups."""
+ ...
+
+ def exclude(
+ self,
+ *args: Any,
+ created_at: datetime | None = None,
+ created_at__gt: datetime | None = None,
+ created_at__gte: datetime | None = None,
+ created_at__lt: datetime | None = None,
+ created_at__lte: datetime | None = None,
+ created_at__between: tuple[datetime, datetime] | None = None,
+ created_at__range: datetime | None = None,
+ created_at__year: int | None = None,
+ created_at__month: int | None = None,
+ created_at__day: int | None = None,
+ created_at__in: list[datetime] | None = None,
+ created_at__isnull: bool | None = None,
+ default_branch: str | None = None,
+ default_branch__contains: str | None = None,
+ default_branch__icontains: str | None = None,
+ default_branch__startswith: str | None = None,
+ default_branch__istartswith: str | None = None,
+ default_branch__endswith: str | None = None,
+ default_branch__iendswith: str | None = None,
+ default_branch__iexact: str | None = None,
+ default_branch__in: list[str] | None = None,
+ default_branch__isnull: bool | None = None,
+ description: str | None = None,
+ description__contains: str | None = None,
+ description__icontains: str | None = None,
+ description__startswith: str | None = None,
+ description__istartswith: str | None = None,
+ description__endswith: str | None = None,
+ description__iendswith: str | None = None,
+ description__iexact: str | None = None,
+ description__in: list[str] | None = None,
+ description__isnull: bool | None = None,
+ id: int | None = None,
+ id__gt: int | None = None,
+ id__gte: int | None = None,
+ id__lt: int | None = None,
+ id__lte: int | None = None,
+ id__between: tuple[int, int] | None = None,
+ id__range: int | None = None,
+ id__in: list[int] | None = None,
+ id__isnull: bool | None = None,
+ name: str | None = None,
+ name__contains: str | None = None,
+ name__icontains: str | None = None,
+ name__startswith: str | None = None,
+ name__istartswith: str | None = None,
+ name__endswith: str | None = None,
+ name__iendswith: str | None = None,
+ name__iexact: str | None = None,
+ name__in: list[str] | None = None,
+ name__isnull: bool | None = None,
+ path: str | None = None,
+ path__contains: str | None = None,
+ path__icontains: str | None = None,
+ path__startswith: str | None = None,
+ path__istartswith: str | None = None,
+ path__endswith: str | None = None,
+ path__iendswith: str | None = None,
+ path__iexact: str | None = None,
+ path__in: list[str] | None = None,
+ path__isnull: bool | None = None,
+ project: Project | None = None,
+ project__in: list[Project] | None = None,
+ project__isnull: bool | None = None,
+ project_id: int | None = None,
+ project_id__gt: int | None = None,
+ project_id__gte: int | None = None,
+ project_id__lt: int | None = None,
+ project_id__lte: int | None = None,
+ project_id__between: tuple[int, int] | None = None,
+ project_id__range: int | None = None,
+ project_id__in: list[int] | None = None,
+ project_id__isnull: bool | None = None,
+ public: bool | None = None,
+ public__in: list[bool] | None = None,
+ public__isnull: bool | None = None,
+ test_command: str | None = None,
+ test_command__contains: str | None = None,
+ test_command__icontains: str | None = None,
+ test_command__startswith: str | None = None,
+ test_command__istartswith: str | None = None,
+ test_command__endswith: str | None = None,
+ test_command__iendswith: str | None = None,
+ test_command__iexact: str | None = None,
+ test_command__in: list[str] | None = None,
+ test_command__isnull: bool | None = None,
+ tests_enabled: bool | None = None,
+ tests_enabled__in: list[bool] | None = None,
+ tests_enabled__isnull: bool | None = None,
+ updated_at: datetime | None = None,
+ updated_at__gt: datetime | None = None,
+ updated_at__gte: datetime | None = None,
+ updated_at__lt: datetime | None = None,
+ updated_at__lte: datetime | None = None,
+ updated_at__between: tuple[datetime, datetime] | None = None,
+ updated_at__range: datetime | None = None,
+ updated_at__year: int | None = None,
+ updated_at__month: int | None = None,
+ updated_at__day: int | None = None,
+ updated_at__in: list[datetime] | None = None,
+ updated_at__isnull: bool | None = None,
+ webhook_url: str | None = None,
+ webhook_url__contains: str | None = None,
+ webhook_url__icontains: str | None = None,
+ webhook_url__startswith: str | None = None,
+ webhook_url__istartswith: str | None = None,
+ webhook_url__endswith: str | None = None,
+ webhook_url__iendswith: str | None = None,
+ webhook_url__iexact: str | None = None,
+ webhook_url__in: list[str] | None = None,
+ webhook_url__isnull: bool | None = None,
+ ) -> GitRepoQuery:
+ """Exclude objects matching field lookups."""
+ ...
+
+ def values(self, *fields: Literal["created_at", "default_branch", "description", "id", "name", "path", "project", "project_id", "public", "test_command", "tests_enabled", "updated_at", "webhook_url"]) -> GitRepoQuery: # type: ignore[override]
+ """Return dicts instead of models."""
+ ...
+
+ def values_list(self, *fields: Literal["created_at", "default_branch", "description", "id", "name", "path", "project", "project_id", "public", "test_command", "tests_enabled", "updated_at", "webhook_url"], flat: bool = False) -> GitRepoQuery: # type: ignore[override]
+ """Return tuples/values instead of models."""
+ ...
+
+ def distinct(self, distinct: bool = True) -> GitRepoQuery:
+ """Return distinct results."""
+ ...
+
+ def join(self, *paths: str) -> GitRepoQuery:
+ """Perform LEFT JOIN for relations."""
+ ...
+
+ def prefetch(self, *paths: str) -> GitRepoQuery:
+ """Prefetch related objects (separate queries)."""
+ ...
+
+ def for_update(self) -> GitRepoQuery:
+ """Add FOR UPDATE lock to query."""
+ ...
+
+ def for_share(self) -> GitRepoQuery:
+ """Add FOR SHARE lock to query."""
+ ...
+
+ # Terminal methods (async, execute query)
+
+ async def get(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ **filters: Any,
+ ) -> GitRepo:
+ """Get single object matching lookups."""
+ ...
+
+ async def get_or_none(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ **filters: Any,
+ ) -> GitRepo | None:
+ """Get object or None if not found."""
+ ...
+
+ async def get_or_create(
+ self,
+ *,
+ defaults: dict[str, Any] | None = None,
+ client: Any | None = None,
+ using: str | None = None,
+ **filters: Any,
+ ) -> tuple[GitRepo, bool]:
+ """Get object or create if not found. Returns (object, created)."""
+ ...
+
+ async def update_or_create(
+ self,
+ *,
+ defaults: dict[str, Any] | None = None,
+ client: Any | None = None,
+ using: str | None = None,
+ **filters: Any,
+ ) -> tuple[GitRepo, bool]:
+ """Get object, create if missing, or update it when defaults are provided."""
+ ...
+
+ async def all(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ mode: str = "models",
+ ) -> list[GitRepo]:
+ """Get all objects."""
+ ...
+
+ async def first(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> GitRepo | None:
+ """Get first object."""
+ ...
+
+ async def last(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> GitRepo | None:
+ """Get last object."""
+ ...
+
+ async def count(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> int:
+ """Count all objects."""
+ ...
+
+ async def sum(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Calculate sum of field values."""
+ ...
+
+ async def avg(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Calculate average of field values."""
+ ...
+
+ async def max(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Get maximum field value."""
+ ...
+
+ async def min(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Get minimum field value."""
+ ...
+
+ async def create( # type: ignore[override]
+ self,
+ *,
+ instance: GitRepo | None = None,
+ client: Any | None = None,
+ using: str | None = None,
+ created_at: datetime | None = None,
+ default_branch: str | None = None,
+ description: str | None = None,
+ id: int | None = None,
+ name: str | None = None,
+ path: str | None = None,
+ project: Project | None = None,
+ project_id: int | None = None,
+ public: bool | None = None,
+ test_command: str | None = None,
+ tests_enabled: bool | None = None,
+ updated_at: datetime | None = None,
+ webhook_url: str | None = None,
+ ) -> GitRepo:
+ """Create new object."""
+ ...
+
+ async def bulk_create( # type: ignore[override]
+ self,
+ objects: list[GitRepo],
+ *,
+ batch_size: int | None = None,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> list[GitRepo]:
+ """Bulk create objects."""
+ ...
+
+ async def bulk_update( # type: ignore[override]
+ self,
+ objects: list[GitRepo],
+ fields: list[str],
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> int:
+ """Bulk update objects."""
+ ...
+
+
+class GitPermission(Model):
+ class Meta:
+ is_table: bool
+ table_name: str
+ id: int | None
+ repo: GitRepo | None
+ user_email: str
+ access: str
+ created_at: datetime | None
+ repo_id: int | None
+ objects: ClassVar["GitPermissionManager"]
+
+
+class GitPermissionQuery(Query[GitPermission]):
+ """Type-safe Query for GitPermission model."""
+
+ # Query building methods (sync, return Query)
+
+ def filter(
+ self,
+ *args: Any,
+ access: str | None = None,
+ access__contains: str | None = None,
+ access__icontains: str | None = None,
+ access__startswith: str | None = None,
+ access__istartswith: str | None = None,
+ access__endswith: str | None = None,
+ access__iendswith: str | None = None,
+ access__iexact: str | None = None,
+ access__in: list[str] | None = None,
+ access__isnull: bool | None = None,
+ created_at: datetime | None = None,
+ created_at__gt: datetime | None = None,
+ created_at__gte: datetime | None = None,
+ created_at__lt: datetime | None = None,
+ created_at__lte: datetime | None = None,
+ created_at__between: tuple[datetime, datetime] | None = None,
+ created_at__range: datetime | None = None,
+ created_at__year: int | None = None,
+ created_at__month: int | None = None,
+ created_at__day: int | None = None,
+ created_at__in: list[datetime] | None = None,
+ created_at__isnull: bool | None = None,
+ id: int | None = None,
+ id__gt: int | None = None,
+ id__gte: int | None = None,
+ id__lt: int | None = None,
+ id__lte: int | None = None,
+ id__between: tuple[int, int] | None = None,
+ id__range: int | None = None,
+ id__in: list[int] | None = None,
+ id__isnull: bool | None = None,
+ repo: GitRepo | None = None,
+ repo__in: list[GitRepo] | None = None,
+ repo__isnull: bool | None = None,
+ repo_id: int | None = None,
+ repo_id__gt: int | None = None,
+ repo_id__gte: int | None = None,
+ repo_id__lt: int | None = None,
+ repo_id__lte: int | None = None,
+ repo_id__between: tuple[int, int] | None = None,
+ repo_id__range: int | None = None,
+ repo_id__in: list[int] | None = None,
+ repo_id__isnull: bool | None = None,
+ user_email: str | None = None,
+ user_email__contains: str | None = None,
+ user_email__icontains: str | None = None,
+ user_email__startswith: str | None = None,
+ user_email__istartswith: str | None = None,
+ user_email__endswith: str | None = None,
+ user_email__iendswith: str | None = None,
+ user_email__iexact: str | None = None,
+ user_email__in: list[str] | None = None,
+ user_email__isnull: bool | None = None,
+ ) -> "GitPermissionQuery":
+ """Filter by Q-expressions or field lookups."""
+ ...
+
+ def exclude(
+ self,
+ *args: Any,
+ access: str | None = None,
+ access__contains: str | None = None,
+ access__icontains: str | None = None,
+ access__startswith: str | None = None,
+ access__istartswith: str | None = None,
+ access__endswith: str | None = None,
+ access__iendswith: str | None = None,
+ access__iexact: str | None = None,
+ access__in: list[str] | None = None,
+ access__isnull: bool | None = None,
+ created_at: datetime | None = None,
+ created_at__gt: datetime | None = None,
+ created_at__gte: datetime | None = None,
+ created_at__lt: datetime | None = None,
+ created_at__lte: datetime | None = None,
+ created_at__between: tuple[datetime, datetime] | None = None,
+ created_at__range: datetime | None = None,
+ created_at__year: int | None = None,
+ created_at__month: int | None = None,
+ created_at__day: int | None = None,
+ created_at__in: list[datetime] | None = None,
+ created_at__isnull: bool | None = None,
+ id: int | None = None,
+ id__gt: int | None = None,
+ id__gte: int | None = None,
+ id__lt: int | None = None,
+ id__lte: int | None = None,
+ id__between: tuple[int, int] | None = None,
+ id__range: int | None = None,
+ id__in: list[int] | None = None,
+ id__isnull: bool | None = None,
+ repo: GitRepo | None = None,
+ repo__in: list[GitRepo] | None = None,
+ repo__isnull: bool | None = None,
+ repo_id: int | None = None,
+ repo_id__gt: int | None = None,
+ repo_id__gte: int | None = None,
+ repo_id__lt: int | None = None,
+ repo_id__lte: int | None = None,
+ repo_id__between: tuple[int, int] | None = None,
+ repo_id__range: int | None = None,
+ repo_id__in: list[int] | None = None,
+ repo_id__isnull: bool | None = None,
+ user_email: str | None = None,
+ user_email__contains: str | None = None,
+ user_email__icontains: str | None = None,
+ user_email__startswith: str | None = None,
+ user_email__istartswith: str | None = None,
+ user_email__endswith: str | None = None,
+ user_email__iendswith: str | None = None,
+ user_email__iexact: str | None = None,
+ user_email__in: list[str] | None = None,
+ user_email__isnull: bool | None = None,
+ ) -> "GitPermissionQuery":
+ """Exclude objects matching field lookups."""
+ ...
+
+ def order_by(self, *fields: Literal["access", "-access", "created_at", "-created_at", "id", "-id", "repo", "-repo", "repo_id", "-repo_id", "user_email", "-user_email"]) -> "GitPermissionQuery": # type: ignore[override]
+ """Order results by fields."""
+ ...
+
+ def limit(self, n: int) -> "GitPermissionQuery":
+ """Limit number of results."""
+ ...
+
+ def offset(self, n: int) -> "GitPermissionQuery":
+ """Skip first n results."""
+ ...
+
+ def distinct(self, value: bool = True) -> "GitPermissionQuery":
+ """Return distinct results."""
+ ...
+
+ def select(self, *fields: Literal["access", "created_at", "id", "repo", "repo_id", "user_email"]) -> "GitPermissionQuery": # type: ignore[override]
+ """Select specific fields."""
+ ...
+
+ def join(self, *paths: str) -> "GitPermissionQuery":
+ """Perform LEFT JOIN for relations."""
+ ...
+
+ def prefetch(self, *paths: str) -> "GitPermissionQuery":
+ """Prefetch related objects (separate queries)."""
+ ...
+
+ def for_update(self) -> "GitPermissionQuery":
+ """Add FOR UPDATE lock to query."""
+ ...
+
+ def for_share(self) -> "GitPermissionQuery":
+ """Add FOR SHARE lock to query."""
+ ...
+
+ def annotate(self, **annotations: Any) -> "GitPermissionQuery":
+ """Add computed fields using aggregate functions."""
+ ...
+
+ def group_by(self, *fields: Literal["access", "created_at", "id", "repo", "repo_id", "user_email"]) -> "GitPermissionQuery": # type: ignore[override]
+ """Add GROUP BY clause."""
+ ...
+
+ def having(self, *q_exprs: Any, **kwargs: Any) -> "GitPermissionQuery":
+ """Add HAVING clause for filtering grouped results."""
+ ...
+
+ def values(self, *fields: Literal["access", "created_at", "id", "repo", "repo_id", "user_email"]) -> "GitPermissionQuery": # type: ignore[override]
+ """Return dicts instead of models."""
+ ...
+
+ def values_list(self, *fields: Literal["access", "created_at", "id", "repo", "repo_id", "user_email"], flat: bool = False) -> "GitPermissionQuery": # type: ignore[override]
+ """Return tuples/values instead of models."""
+ ...
+
+ # Terminal methods (async, execute query)
+
+ async def all(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> list[GitPermission]:
+ """Execute query and return all results."""
+ ...
+
+ async def first(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> GitPermission | None:
+ """Execute query and return first result."""
+ ...
+
+ async def last(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> GitPermission | None:
+ """Execute query and return last result."""
+ ...
+
+ async def count(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> int:
+ """Count matching objects."""
+ ...
+
+ async def sum(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Calculate sum of field values."""
+ ...
+
+ async def avg(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Calculate average of field values."""
+ ...
+
+ async def max(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Get maximum field value."""
+ ...
+
+ async def min(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Get minimum field value."""
+ ...
+
+ async def update( # type: ignore[override]
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ **values: Any,
+ ) -> int:
+ """Update matching objects."""
+ ...
+
+ async def increment(
+ self,
+ field: str,
+ by: int | float = 1,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> int:
+ """Atomically increment a field value."""
+ ...
+
+ async def delete(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> int:
+ """Delete matching objects."""
+ ...
+
+class GitPermissionManager(QueryManager[GitPermission]):
+ """Type-safe Manager for GitPermission model."""
+
+ # Query building methods (sync, return Query)
+
+ def query(self) -> GitPermissionQuery:
+ """Return a Query builder for this model."""
+ ...
+
+ def filter(
+ self,
+ *args: Any,
+ access: str | None = None,
+ access__contains: str | None = None,
+ access__icontains: str | None = None,
+ access__startswith: str | None = None,
+ access__istartswith: str | None = None,
+ access__endswith: str | None = None,
+ access__iendswith: str | None = None,
+ access__iexact: str | None = None,
+ access__in: list[str] | None = None,
+ access__isnull: bool | None = None,
+ created_at: datetime | None = None,
+ created_at__gt: datetime | None = None,
+ created_at__gte: datetime | None = None,
+ created_at__lt: datetime | None = None,
+ created_at__lte: datetime | None = None,
+ created_at__between: tuple[datetime, datetime] | None = None,
+ created_at__range: datetime | None = None,
+ created_at__year: int | None = None,
+ created_at__month: int | None = None,
+ created_at__day: int | None = None,
+ created_at__in: list[datetime] | None = None,
+ created_at__isnull: bool | None = None,
+ id: int | None = None,
+ id__gt: int | None = None,
+ id__gte: int | None = None,
+ id__lt: int | None = None,
+ id__lte: int | None = None,
+ id__between: tuple[int, int] | None = None,
+ id__range: int | None = None,
+ id__in: list[int] | None = None,
+ id__isnull: bool | None = None,
+ repo: GitRepo | None = None,
+ repo__in: list[GitRepo] | None = None,
+ repo__isnull: bool | None = None,
+ repo_id: int | None = None,
+ repo_id__gt: int | None = None,
+ repo_id__gte: int | None = None,
+ repo_id__lt: int | None = None,
+ repo_id__lte: int | None = None,
+ repo_id__between: tuple[int, int] | None = None,
+ repo_id__range: int | None = None,
+ repo_id__in: list[int] | None = None,
+ repo_id__isnull: bool | None = None,
+ user_email: str | None = None,
+ user_email__contains: str | None = None,
+ user_email__icontains: str | None = None,
+ user_email__startswith: str | None = None,
+ user_email__istartswith: str | None = None,
+ user_email__endswith: str | None = None,
+ user_email__iendswith: str | None = None,
+ user_email__iexact: str | None = None,
+ user_email__in: list[str] | None = None,
+ user_email__isnull: bool | None = None,
+ ) -> GitPermissionQuery:
+ """Filter by Q-expressions or field lookups."""
+ ...
+
+ def exclude(
+ self,
+ *args: Any,
+ access: str | None = None,
+ access__contains: str | None = None,
+ access__icontains: str | None = None,
+ access__startswith: str | None = None,
+ access__istartswith: str | None = None,
+ access__endswith: str | None = None,
+ access__iendswith: str | None = None,
+ access__iexact: str | None = None,
+ access__in: list[str] | None = None,
+ access__isnull: bool | None = None,
+ created_at: datetime | None = None,
+ created_at__gt: datetime | None = None,
+ created_at__gte: datetime | None = None,
+ created_at__lt: datetime | None = None,
+ created_at__lte: datetime | None = None,
+ created_at__between: tuple[datetime, datetime] | None = None,
+ created_at__range: datetime | None = None,
+ created_at__year: int | None = None,
+ created_at__month: int | None = None,
+ created_at__day: int | None = None,
+ created_at__in: list[datetime] | None = None,
+ created_at__isnull: bool | None = None,
+ id: int | None = None,
+ id__gt: int | None = None,
+ id__gte: int | None = None,
+ id__lt: int | None = None,
+ id__lte: int | None = None,
+ id__between: tuple[int, int] | None = None,
+ id__range: int | None = None,
+ id__in: list[int] | None = None,
+ id__isnull: bool | None = None,
+ repo: GitRepo | None = None,
+ repo__in: list[GitRepo] | None = None,
+ repo__isnull: bool | None = None,
+ repo_id: int | None = None,
+ repo_id__gt: int | None = None,
+ repo_id__gte: int | None = None,
+ repo_id__lt: int | None = None,
+ repo_id__lte: int | None = None,
+ repo_id__between: tuple[int, int] | None = None,
+ repo_id__range: int | None = None,
+ repo_id__in: list[int] | None = None,
+ repo_id__isnull: bool | None = None,
+ user_email: str | None = None,
+ user_email__contains: str | None = None,
+ user_email__icontains: str | None = None,
+ user_email__startswith: str | None = None,
+ user_email__istartswith: str | None = None,
+ user_email__endswith: str | None = None,
+ user_email__iendswith: str | None = None,
+ user_email__iexact: str | None = None,
+ user_email__in: list[str] | None = None,
+ user_email__isnull: bool | None = None,
+ ) -> GitPermissionQuery:
+ """Exclude objects matching field lookups."""
+ ...
+
+ def values(self, *fields: Literal["access", "created_at", "id", "repo", "repo_id", "user_email"]) -> GitPermissionQuery: # type: ignore[override]
+ """Return dicts instead of models."""
+ ...
+
+ def values_list(self, *fields: Literal["access", "created_at", "id", "repo", "repo_id", "user_email"], flat: bool = False) -> GitPermissionQuery: # type: ignore[override]
+ """Return tuples/values instead of models."""
+ ...
+
+ def distinct(self, distinct: bool = True) -> GitPermissionQuery:
+ """Return distinct results."""
+ ...
+
+ def join(self, *paths: str) -> GitPermissionQuery:
+ """Perform LEFT JOIN for relations."""
+ ...
+
+ def prefetch(self, *paths: str) -> GitPermissionQuery:
+ """Prefetch related objects (separate queries)."""
+ ...
+
+ def for_update(self) -> GitPermissionQuery:
+ """Add FOR UPDATE lock to query."""
+ ...
+
+ def for_share(self) -> GitPermissionQuery:
+ """Add FOR SHARE lock to query."""
+ ...
+
+ # Terminal methods (async, execute query)
+
+ async def get(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ **filters: Any,
+ ) -> GitPermission:
+ """Get single object matching lookups."""
+ ...
+
+ async def get_or_none(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ **filters: Any,
+ ) -> GitPermission | None:
+ """Get object or None if not found."""
+ ...
+
+ async def get_or_create(
+ self,
+ *,
+ defaults: dict[str, Any] | None = None,
+ client: Any | None = None,
+ using: str | None = None,
+ **filters: Any,
+ ) -> tuple[GitPermission, bool]:
+ """Get object or create if not found. Returns (object, created)."""
+ ...
+
+ async def update_or_create(
+ self,
+ *,
+ defaults: dict[str, Any] | None = None,
+ client: Any | None = None,
+ using: str | None = None,
+ **filters: Any,
+ ) -> tuple[GitPermission, bool]:
+ """Get object, create if missing, or update it when defaults are provided."""
+ ...
+
+ async def all(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ mode: str = "models",
+ ) -> list[GitPermission]:
+ """Get all objects."""
+ ...
+
+ async def first(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> GitPermission | None:
+ """Get first object."""
+ ...
+
+ async def last(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> GitPermission | None:
+ """Get last object."""
+ ...
+
+ async def count(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> int:
+ """Count all objects."""
+ ...
+
+ async def sum(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Calculate sum of field values."""
+ ...
+
+ async def avg(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Calculate average of field values."""
+ ...
+
+ async def max(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Get maximum field value."""
+ ...
+
+ async def min(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Get minimum field value."""
+ ...
+
+ async def create( # type: ignore[override]
+ self,
+ *,
+ instance: GitPermission | None = None,
+ client: Any | None = None,
+ using: str | None = None,
+ access: str | None = None,
+ created_at: datetime | None = None,
+ id: int | None = None,
+ repo: GitRepo | None = None,
+ repo_id: int | None = None,
+ user_email: str | None = None,
+ ) -> GitPermission:
+ """Create new object."""
+ ...
+
+ async def bulk_create( # type: ignore[override]
+ self,
+ objects: list[GitPermission],
+ *,
+ batch_size: int | None = None,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> list[GitPermission]:
+ """Bulk create objects."""
+ ...
+
+ async def bulk_update( # type: ignore[override]
+ self,
+ objects: list[GitPermission],
+ fields: list[str],
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> int:
+ """Bulk update objects."""
+ ...
+
+
+class GitPushLog(Model):
+ class Meta:
+ is_table: bool
+ table_name: str
+ id: int | None
+ repo: GitRepo | None
+ ref: str
+ old_rev: str | None
+ new_rev: str | None
+ pusher_email: str
+ status: str
+ output: str | None
+ created_at: datetime | None
+ updated_at: datetime | None
+ repo_id: int | None
+ objects: ClassVar["GitPushLogManager"]
+
+
+class GitPushLogQuery(Query[GitPushLog]):
+ """Type-safe Query for GitPushLog model."""
+
+ # Query building methods (sync, return Query)
+
+ def filter(
+ self,
+ *args: Any,
+ created_at: datetime | None = None,
+ created_at__gt: datetime | None = None,
+ created_at__gte: datetime | None = None,
+ created_at__lt: datetime | None = None,
+ created_at__lte: datetime | None = None,
+ created_at__between: tuple[datetime, datetime] | None = None,
+ created_at__range: datetime | None = None,
+ created_at__year: int | None = None,
+ created_at__month: int | None = None,
+ created_at__day: int | None = None,
+ created_at__in: list[datetime] | None = None,
+ created_at__isnull: bool | None = None,
+ id: int | None = None,
+ id__gt: int | None = None,
+ id__gte: int | None = None,
+ id__lt: int | None = None,
+ id__lte: int | None = None,
+ id__between: tuple[int, int] | None = None,
+ id__range: int | None = None,
+ id__in: list[int] | None = None,
+ id__isnull: bool | None = None,
+ new_rev: str | None = None,
+ new_rev__contains: str | None = None,
+ new_rev__icontains: str | None = None,
+ new_rev__startswith: str | None = None,
+ new_rev__istartswith: str | None = None,
+ new_rev__endswith: str | None = None,
+ new_rev__iendswith: str | None = None,
+ new_rev__iexact: str | None = None,
+ new_rev__in: list[str] | None = None,
+ new_rev__isnull: bool | None = None,
+ old_rev: str | None = None,
+ old_rev__contains: str | None = None,
+ old_rev__icontains: str | None = None,
+ old_rev__startswith: str | None = None,
+ old_rev__istartswith: str | None = None,
+ old_rev__endswith: str | None = None,
+ old_rev__iendswith: str | None = None,
+ old_rev__iexact: str | None = None,
+ old_rev__in: list[str] | None = None,
+ old_rev__isnull: bool | None = None,
+ output: str | None = None,
+ output__contains: str | None = None,
+ output__icontains: str | None = None,
+ output__startswith: str | None = None,
+ output__istartswith: str | None = None,
+ output__endswith: str | None = None,
+ output__iendswith: str | None = None,
+ output__iexact: str | None = None,
+ output__in: list[str] | None = None,
+ output__isnull: bool | None = None,
+ pusher_email: str | None = None,
+ pusher_email__contains: str | None = None,
+ pusher_email__icontains: str | None = None,
+ pusher_email__startswith: str | None = None,
+ pusher_email__istartswith: str | None = None,
+ pusher_email__endswith: str | None = None,
+ pusher_email__iendswith: str | None = None,
+ pusher_email__iexact: str | None = None,
+ pusher_email__in: list[str] | None = None,
+ pusher_email__isnull: bool | None = None,
+ ref: str | None = None,
+ ref__contains: str | None = None,
+ ref__icontains: str | None = None,
+ ref__startswith: str | None = None,
+ ref__istartswith: str | None = None,
+ ref__endswith: str | None = None,
+ ref__iendswith: str | None = None,
+ ref__iexact: str | None = None,
+ ref__in: list[str] | None = None,
+ ref__isnull: bool | None = None,
+ repo: GitRepo | None = None,
+ repo__in: list[GitRepo] | None = None,
+ repo__isnull: bool | None = None,
+ repo_id: int | None = None,
+ repo_id__gt: int | None = None,
+ repo_id__gte: int | None = None,
+ repo_id__lt: int | None = None,
+ repo_id__lte: int | None = None,
+ repo_id__between: tuple[int, int] | None = None,
+ repo_id__range: int | None = None,
+ repo_id__in: list[int] | None = None,
+ repo_id__isnull: bool | None = None,
+ status: str | None = None,
+ status__contains: str | None = None,
+ status__icontains: str | None = None,
+ status__startswith: str | None = None,
+ status__istartswith: str | None = None,
+ status__endswith: str | None = None,
+ status__iendswith: str | None = None,
+ status__iexact: str | None = None,
+ status__in: list[str] | None = None,
+ status__isnull: bool | None = None,
+ updated_at: datetime | None = None,
+ updated_at__gt: datetime | None = None,
+ updated_at__gte: datetime | None = None,
+ updated_at__lt: datetime | None = None,
+ updated_at__lte: datetime | None = None,
+ updated_at__between: tuple[datetime, datetime] | None = None,
+ updated_at__range: datetime | None = None,
+ updated_at__year: int | None = None,
+ updated_at__month: int | None = None,
+ updated_at__day: int | None = None,
+ updated_at__in: list[datetime] | None = None,
+ updated_at__isnull: bool | None = None,
+ ) -> "GitPushLogQuery":
+ """Filter by Q-expressions or field lookups."""
+ ...
+
+ def exclude(
+ self,
+ *args: Any,
+ created_at: datetime | None = None,
+ created_at__gt: datetime | None = None,
+ created_at__gte: datetime | None = None,
+ created_at__lt: datetime | None = None,
+ created_at__lte: datetime | None = None,
+ created_at__between: tuple[datetime, datetime] | None = None,
+ created_at__range: datetime | None = None,
+ created_at__year: int | None = None,
+ created_at__month: int | None = None,
+ created_at__day: int | None = None,
+ created_at__in: list[datetime] | None = None,
+ created_at__isnull: bool | None = None,
+ id: int | None = None,
+ id__gt: int | None = None,
+ id__gte: int | None = None,
+ id__lt: int | None = None,
+ id__lte: int | None = None,
+ id__between: tuple[int, int] | None = None,
+ id__range: int | None = None,
+ id__in: list[int] | None = None,
+ id__isnull: bool | None = None,
+ new_rev: str | None = None,
+ new_rev__contains: str | None = None,
+ new_rev__icontains: str | None = None,
+ new_rev__startswith: str | None = None,
+ new_rev__istartswith: str | None = None,
+ new_rev__endswith: str | None = None,
+ new_rev__iendswith: str | None = None,
+ new_rev__iexact: str | None = None,
+ new_rev__in: list[str] | None = None,
+ new_rev__isnull: bool | None = None,
+ old_rev: str | None = None,
+ old_rev__contains: str | None = None,
+ old_rev__icontains: str | None = None,
+ old_rev__startswith: str | None = None,
+ old_rev__istartswith: str | None = None,
+ old_rev__endswith: str | None = None,
+ old_rev__iendswith: str | None = None,
+ old_rev__iexact: str | None = None,
+ old_rev__in: list[str] | None = None,
+ old_rev__isnull: bool | None = None,
+ output: str | None = None,
+ output__contains: str | None = None,
+ output__icontains: str | None = None,
+ output__startswith: str | None = None,
+ output__istartswith: str | None = None,
+ output__endswith: str | None = None,
+ output__iendswith: str | None = None,
+ output__iexact: str | None = None,
+ output__in: list[str] | None = None,
+ output__isnull: bool | None = None,
+ pusher_email: str | None = None,
+ pusher_email__contains: str | None = None,
+ pusher_email__icontains: str | None = None,
+ pusher_email__startswith: str | None = None,
+ pusher_email__istartswith: str | None = None,
+ pusher_email__endswith: str | None = None,
+ pusher_email__iendswith: str | None = None,
+ pusher_email__iexact: str | None = None,
+ pusher_email__in: list[str] | None = None,
+ pusher_email__isnull: bool | None = None,
+ ref: str | None = None,
+ ref__contains: str | None = None,
+ ref__icontains: str | None = None,
+ ref__startswith: str | None = None,
+ ref__istartswith: str | None = None,
+ ref__endswith: str | None = None,
+ ref__iendswith: str | None = None,
+ ref__iexact: str | None = None,
+ ref__in: list[str] | None = None,
+ ref__isnull: bool | None = None,
+ repo: GitRepo | None = None,
+ repo__in: list[GitRepo] | None = None,
+ repo__isnull: bool | None = None,
+ repo_id: int | None = None,
+ repo_id__gt: int | None = None,
+ repo_id__gte: int | None = None,
+ repo_id__lt: int | None = None,
+ repo_id__lte: int | None = None,
+ repo_id__between: tuple[int, int] | None = None,
+ repo_id__range: int | None = None,
+ repo_id__in: list[int] | None = None,
+ repo_id__isnull: bool | None = None,
+ status: str | None = None,
+ status__contains: str | None = None,
+ status__icontains: str | None = None,
+ status__startswith: str | None = None,
+ status__istartswith: str | None = None,
+ status__endswith: str | None = None,
+ status__iendswith: str | None = None,
+ status__iexact: str | None = None,
+ status__in: list[str] | None = None,
+ status__isnull: bool | None = None,
+ updated_at: datetime | None = None,
+ updated_at__gt: datetime | None = None,
+ updated_at__gte: datetime | None = None,
+ updated_at__lt: datetime | None = None,
+ updated_at__lte: datetime | None = None,
+ updated_at__between: tuple[datetime, datetime] | None = None,
+ updated_at__range: datetime | None = None,
+ updated_at__year: int | None = None,
+ updated_at__month: int | None = None,
+ updated_at__day: int | None = None,
+ updated_at__in: list[datetime] | None = None,
+ updated_at__isnull: bool | None = None,
+ ) -> "GitPushLogQuery":
+ """Exclude objects matching field lookups."""
+ ...
+
+ def order_by(self, *fields: Literal["created_at", "-created_at", "id", "-id", "new_rev", "-new_rev", "old_rev", "-old_rev", "output", "-output", "pusher_email", "-pusher_email", "ref", "-ref", "repo", "-repo", "repo_id", "-repo_id", "status", "-status", "updated_at", "-updated_at"]) -> "GitPushLogQuery": # type: ignore[override]
+ """Order results by fields."""
+ ...
+
+ def limit(self, n: int) -> "GitPushLogQuery":
+ """Limit number of results."""
+ ...
+
+ def offset(self, n: int) -> "GitPushLogQuery":
+ """Skip first n results."""
+ ...
+
+ def distinct(self, value: bool = True) -> "GitPushLogQuery":
+ """Return distinct results."""
+ ...
+
+ def select(self, *fields: Literal["created_at", "id", "new_rev", "old_rev", "output", "pusher_email", "ref", "repo", "repo_id", "status", "updated_at"]) -> "GitPushLogQuery": # type: ignore[override]
+ """Select specific fields."""
+ ...
+
+ def join(self, *paths: str) -> "GitPushLogQuery":
+ """Perform LEFT JOIN for relations."""
+ ...
+
+ def prefetch(self, *paths: str) -> "GitPushLogQuery":
+ """Prefetch related objects (separate queries)."""
+ ...
+
+ def for_update(self) -> "GitPushLogQuery":
+ """Add FOR UPDATE lock to query."""
+ ...
+
+ def for_share(self) -> "GitPushLogQuery":
+ """Add FOR SHARE lock to query."""
+ ...
+
+ def annotate(self, **annotations: Any) -> "GitPushLogQuery":
+ """Add computed fields using aggregate functions."""
+ ...
+
+ def group_by(self, *fields: Literal["created_at", "id", "new_rev", "old_rev", "output", "pusher_email", "ref", "repo", "repo_id", "status", "updated_at"]) -> "GitPushLogQuery": # type: ignore[override]
+ """Add GROUP BY clause."""
+ ...
+
+ def having(self, *q_exprs: Any, **kwargs: Any) -> "GitPushLogQuery":
+ """Add HAVING clause for filtering grouped results."""
+ ...
+
+ def values(self, *fields: Literal["created_at", "id", "new_rev", "old_rev", "output", "pusher_email", "ref", "repo", "repo_id", "status", "updated_at"]) -> "GitPushLogQuery": # type: ignore[override]
+ """Return dicts instead of models."""
+ ...
+
+ def values_list(self, *fields: Literal["created_at", "id", "new_rev", "old_rev", "output", "pusher_email", "ref", "repo", "repo_id", "status", "updated_at"], flat: bool = False) -> "GitPushLogQuery": # type: ignore[override]
+ """Return tuples/values instead of models."""
+ ...
+
+ # Terminal methods (async, execute query)
+
+ async def all(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> list[GitPushLog]:
+ """Execute query and return all results."""
+ ...
+
+ async def first(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> GitPushLog | None:
+ """Execute query and return first result."""
+ ...
+
+ async def last(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> GitPushLog | None:
+ """Execute query and return last result."""
+ ...
+
+ async def count(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> int:
+ """Count matching objects."""
+ ...
+
+ async def sum(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Calculate sum of field values."""
+ ...
+
+ async def avg(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Calculate average of field values."""
+ ...
+
+ async def max(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Get maximum field value."""
+ ...
+
+ async def min(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Get minimum field value."""
+ ...
+
+ async def update( # type: ignore[override]
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ **values: Any,
+ ) -> int:
+ """Update matching objects."""
+ ...
+
+ async def increment(
+ self,
+ field: str,
+ by: int | float = 1,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> int:
+ """Atomically increment a field value."""
+ ...
+
+ async def delete(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> int:
+ """Delete matching objects."""
+ ...
+
+class GitPushLogManager(QueryManager[GitPushLog]):
+ """Type-safe Manager for GitPushLog model."""
+
+ # Query building methods (sync, return Query)
+
+ def query(self) -> GitPushLogQuery:
+ """Return a Query builder for this model."""
+ ...
+
+ def filter(
+ self,
+ *args: Any,
+ created_at: datetime | None = None,
+ created_at__gt: datetime | None = None,
+ created_at__gte: datetime | None = None,
+ created_at__lt: datetime | None = None,
+ created_at__lte: datetime | None = None,
+ created_at__between: tuple[datetime, datetime] | None = None,
+ created_at__range: datetime | None = None,
+ created_at__year: int | None = None,
+ created_at__month: int | None = None,
+ created_at__day: int | None = None,
+ created_at__in: list[datetime] | None = None,
+ created_at__isnull: bool | None = None,
+ id: int | None = None,
+ id__gt: int | None = None,
+ id__gte: int | None = None,
+ id__lt: int | None = None,
+ id__lte: int | None = None,
+ id__between: tuple[int, int] | None = None,
+ id__range: int | None = None,
+ id__in: list[int] | None = None,
+ id__isnull: bool | None = None,
+ new_rev: str | None = None,
+ new_rev__contains: str | None = None,
+ new_rev__icontains: str | None = None,
+ new_rev__startswith: str | None = None,
+ new_rev__istartswith: str | None = None,
+ new_rev__endswith: str | None = None,
+ new_rev__iendswith: str | None = None,
+ new_rev__iexact: str | None = None,
+ new_rev__in: list[str] | None = None,
+ new_rev__isnull: bool | None = None,
+ old_rev: str | None = None,
+ old_rev__contains: str | None = None,
+ old_rev__icontains: str | None = None,
+ old_rev__startswith: str | None = None,
+ old_rev__istartswith: str | None = None,
+ old_rev__endswith: str | None = None,
+ old_rev__iendswith: str | None = None,
+ old_rev__iexact: str | None = None,
+ old_rev__in: list[str] | None = None,
+ old_rev__isnull: bool | None = None,
+ output: str | None = None,
+ output__contains: str | None = None,
+ output__icontains: str | None = None,
+ output__startswith: str | None = None,
+ output__istartswith: str | None = None,
+ output__endswith: str | None = None,
+ output__iendswith: str | None = None,
+ output__iexact: str | None = None,
+ output__in: list[str] | None = None,
+ output__isnull: bool | None = None,
+ pusher_email: str | None = None,
+ pusher_email__contains: str | None = None,
+ pusher_email__icontains: str | None = None,
+ pusher_email__startswith: str | None = None,
+ pusher_email__istartswith: str | None = None,
+ pusher_email__endswith: str | None = None,
+ pusher_email__iendswith: str | None = None,
+ pusher_email__iexact: str | None = None,
+ pusher_email__in: list[str] | None = None,
+ pusher_email__isnull: bool | None = None,
+ ref: str | None = None,
+ ref__contains: str | None = None,
+ ref__icontains: str | None = None,
+ ref__startswith: str | None = None,
+ ref__istartswith: str | None = None,
+ ref__endswith: str | None = None,
+ ref__iendswith: str | None = None,
+ ref__iexact: str | None = None,
+ ref__in: list[str] | None = None,
+ ref__isnull: bool | None = None,
+ repo: GitRepo | None = None,
+ repo__in: list[GitRepo] | None = None,
+ repo__isnull: bool | None = None,
+ repo_id: int | None = None,
+ repo_id__gt: int | None = None,
+ repo_id__gte: int | None = None,
+ repo_id__lt: int | None = None,
+ repo_id__lte: int | None = None,
+ repo_id__between: tuple[int, int] | None = None,
+ repo_id__range: int | None = None,
+ repo_id__in: list[int] | None = None,
+ repo_id__isnull: bool | None = None,
+ status: str | None = None,
+ status__contains: str | None = None,
+ status__icontains: str | None = None,
+ status__startswith: str | None = None,
+ status__istartswith: str | None = None,
+ status__endswith: str | None = None,
+ status__iendswith: str | None = None,
+ status__iexact: str | None = None,
+ status__in: list[str] | None = None,
+ status__isnull: bool | None = None,
+ updated_at: datetime | None = None,
+ updated_at__gt: datetime | None = None,
+ updated_at__gte: datetime | None = None,
+ updated_at__lt: datetime | None = None,
+ updated_at__lte: datetime | None = None,
+ updated_at__between: tuple[datetime, datetime] | None = None,
+ updated_at__range: datetime | None = None,
+ updated_at__year: int | None = None,
+ updated_at__month: int | None = None,
+ updated_at__day: int | None = None,
+ updated_at__in: list[datetime] | None = None,
+ updated_at__isnull: bool | None = None,
+ ) -> GitPushLogQuery:
+ """Filter by Q-expressions or field lookups."""
+ ...
+
+ def exclude(
+ self,
+ *args: Any,
+ created_at: datetime | None = None,
+ created_at__gt: datetime | None = None,
+ created_at__gte: datetime | None = None,
+ created_at__lt: datetime | None = None,
+ created_at__lte: datetime | None = None,
+ created_at__between: tuple[datetime, datetime] | None = None,
+ created_at__range: datetime | None = None,
+ created_at__year: int | None = None,
+ created_at__month: int | None = None,
+ created_at__day: int | None = None,
+ created_at__in: list[datetime] | None = None,
+ created_at__isnull: bool | None = None,
+ id: int | None = None,
+ id__gt: int | None = None,
+ id__gte: int | None = None,
+ id__lt: int | None = None,
+ id__lte: int | None = None,
+ id__between: tuple[int, int] | None = None,
+ id__range: int | None = None,
+ id__in: list[int] | None = None,
+ id__isnull: bool | None = None,
+ new_rev: str | None = None,
+ new_rev__contains: str | None = None,
+ new_rev__icontains: str | None = None,
+ new_rev__startswith: str | None = None,
+ new_rev__istartswith: str | None = None,
+ new_rev__endswith: str | None = None,
+ new_rev__iendswith: str | None = None,
+ new_rev__iexact: str | None = None,
+ new_rev__in: list[str] | None = None,
+ new_rev__isnull: bool | None = None,
+ old_rev: str | None = None,
+ old_rev__contains: str | None = None,
+ old_rev__icontains: str | None = None,
+ old_rev__startswith: str | None = None,
+ old_rev__istartswith: str | None = None,
+ old_rev__endswith: str | None = None,
+ old_rev__iendswith: str | None = None,
+ old_rev__iexact: str | None = None,
+ old_rev__in: list[str] | None = None,
+ old_rev__isnull: bool | None = None,
+ output: str | None = None,
+ output__contains: str | None = None,
+ output__icontains: str | None = None,
+ output__startswith: str | None = None,
+ output__istartswith: str | None = None,
+ output__endswith: str | None = None,
+ output__iendswith: str | None = None,
+ output__iexact: str | None = None,
+ output__in: list[str] | None = None,
+ output__isnull: bool | None = None,
+ pusher_email: str | None = None,
+ pusher_email__contains: str | None = None,
+ pusher_email__icontains: str | None = None,
+ pusher_email__startswith: str | None = None,
+ pusher_email__istartswith: str | None = None,
+ pusher_email__endswith: str | None = None,
+ pusher_email__iendswith: str | None = None,
+ pusher_email__iexact: str | None = None,
+ pusher_email__in: list[str] | None = None,
+ pusher_email__isnull: bool | None = None,
+ ref: str | None = None,
+ ref__contains: str | None = None,
+ ref__icontains: str | None = None,
+ ref__startswith: str | None = None,
+ ref__istartswith: str | None = None,
+ ref__endswith: str | None = None,
+ ref__iendswith: str | None = None,
+ ref__iexact: str | None = None,
+ ref__in: list[str] | None = None,
+ ref__isnull: bool | None = None,
+ repo: GitRepo | None = None,
+ repo__in: list[GitRepo] | None = None,
+ repo__isnull: bool | None = None,
+ repo_id: int | None = None,
+ repo_id__gt: int | None = None,
+ repo_id__gte: int | None = None,
+ repo_id__lt: int | None = None,
+ repo_id__lte: int | None = None,
+ repo_id__between: tuple[int, int] | None = None,
+ repo_id__range: int | None = None,
+ repo_id__in: list[int] | None = None,
+ repo_id__isnull: bool | None = None,
+ status: str | None = None,
+ status__contains: str | None = None,
+ status__icontains: str | None = None,
+ status__startswith: str | None = None,
+ status__istartswith: str | None = None,
+ status__endswith: str | None = None,
+ status__iendswith: str | None = None,
+ status__iexact: str | None = None,
+ status__in: list[str] | None = None,
+ status__isnull: bool | None = None,
+ updated_at: datetime | None = None,
+ updated_at__gt: datetime | None = None,
+ updated_at__gte: datetime | None = None,
+ updated_at__lt: datetime | None = None,
+ updated_at__lte: datetime | None = None,
+ updated_at__between: tuple[datetime, datetime] | None = None,
+ updated_at__range: datetime | None = None,
+ updated_at__year: int | None = None,
+ updated_at__month: int | None = None,
+ updated_at__day: int | None = None,
+ updated_at__in: list[datetime] | None = None,
+ updated_at__isnull: bool | None = None,
+ ) -> GitPushLogQuery:
+ """Exclude objects matching field lookups."""
+ ...
+
+ def values(self, *fields: Literal["created_at", "id", "new_rev", "old_rev", "output", "pusher_email", "ref", "repo", "repo_id", "status", "updated_at"]) -> GitPushLogQuery: # type: ignore[override]
+ """Return dicts instead of models."""
+ ...
+
+ def values_list(self, *fields: Literal["created_at", "id", "new_rev", "old_rev", "output", "pusher_email", "ref", "repo", "repo_id", "status", "updated_at"], flat: bool = False) -> GitPushLogQuery: # type: ignore[override]
+ """Return tuples/values instead of models."""
+ ...
+
+ def distinct(self, distinct: bool = True) -> GitPushLogQuery:
+ """Return distinct results."""
+ ...
+
+ def join(self, *paths: str) -> GitPushLogQuery:
+ """Perform LEFT JOIN for relations."""
+ ...
+
+ def prefetch(self, *paths: str) -> GitPushLogQuery:
+ """Prefetch related objects (separate queries)."""
+ ...
+
+ def for_update(self) -> GitPushLogQuery:
+ """Add FOR UPDATE lock to query."""
+ ...
+
+ def for_share(self) -> GitPushLogQuery:
+ """Add FOR SHARE lock to query."""
+ ...
+
+ # Terminal methods (async, execute query)
+
+ async def get(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ **filters: Any,
+ ) -> GitPushLog:
+ """Get single object matching lookups."""
+ ...
+
+ async def get_or_none(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ **filters: Any,
+ ) -> GitPushLog | None:
+ """Get object or None if not found."""
+ ...
+
+ async def get_or_create(
+ self,
+ *,
+ defaults: dict[str, Any] | None = None,
+ client: Any | None = None,
+ using: str | None = None,
+ **filters: Any,
+ ) -> tuple[GitPushLog, bool]:
+ """Get object or create if not found. Returns (object, created)."""
+ ...
+
+ async def update_or_create(
+ self,
+ *,
+ defaults: dict[str, Any] | None = None,
+ client: Any | None = None,
+ using: str | None = None,
+ **filters: Any,
+ ) -> tuple[GitPushLog, bool]:
+ """Get object, create if missing, or update it when defaults are provided."""
+ ...
+
+ async def all(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ mode: str = "models",
+ ) -> list[GitPushLog]:
+ """Get all objects."""
+ ...
+
+ async def first(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> GitPushLog | None:
+ """Get first object."""
+ ...
+
+ async def last(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> GitPushLog | None:
+ """Get last object."""
+ ...
+
+ async def count(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> int:
+ """Count all objects."""
+ ...
+
+ async def sum(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Calculate sum of field values."""
+ ...
+
+ async def avg(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Calculate average of field values."""
+ ...
+
+ async def max(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Get maximum field value."""
+ ...
+
+ async def min(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Get minimum field value."""
+ ...
+
+ async def create( # type: ignore[override]
+ self,
+ *,
+ instance: GitPushLog | None = None,
+ client: Any | None = None,
+ using: str | None = None,
+ created_at: datetime | None = None,
+ id: int | None = None,
+ new_rev: str | None = None,
+ old_rev: str | None = None,
+ output: str | None = None,
+ pusher_email: str | None = None,
+ ref: str | None = None,
+ repo: GitRepo | None = None,
+ repo_id: int | None = None,
+ status: str | None = None,
+ updated_at: datetime | None = None,
+ ) -> GitPushLog:
+ """Create new object."""
+ ...
+
+ async def bulk_create( # type: ignore[override]
+ self,
+ objects: list[GitPushLog],
+ *,
+ batch_size: int | None = None,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> list[GitPushLog]:
+ """Bulk create objects."""
+ ...
+
+ async def bulk_update( # type: ignore[override]
+ self,
+ objects: list[GitPushLog],
+ fields: list[str],
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> int:
+ """Bulk update objects."""
+ ...
+
+
+class GitCommitTaskRef(Model):
+ class Meta:
+ is_table: bool
+ table_name: str
+ id: int | None
+ repo: GitRepo | None
+ task_id: int
+ commit_sha: str
+ relation: str
+ created_at: datetime | None
+ repo_id: int | None
+ objects: ClassVar["GitCommitTaskRefManager"]
+
+
+class GitCommitTaskRefQuery(Query[GitCommitTaskRef]):
+ """Type-safe Query for GitCommitTaskRef model."""
+
+ # Query building methods (sync, return Query)
+
+ def filter(
+ self,
+ *args: Any,
+ commit_sha: str | None = None,
+ commit_sha__contains: str | None = None,
+ commit_sha__icontains: str | None = None,
+ commit_sha__startswith: str | None = None,
+ commit_sha__istartswith: str | None = None,
+ commit_sha__endswith: str | None = None,
+ commit_sha__iendswith: str | None = None,
+ commit_sha__iexact: str | None = None,
+ commit_sha__in: list[str] | None = None,
+ commit_sha__isnull: bool | None = None,
+ created_at: datetime | None = None,
+ created_at__gt: datetime | None = None,
+ created_at__gte: datetime | None = None,
+ created_at__lt: datetime | None = None,
+ created_at__lte: datetime | None = None,
+ created_at__between: tuple[datetime, datetime] | None = None,
+ created_at__range: datetime | None = None,
+ created_at__year: int | None = None,
+ created_at__month: int | None = None,
+ created_at__day: int | None = None,
+ created_at__in: list[datetime] | None = None,
+ created_at__isnull: bool | None = None,
+ id: int | None = None,
+ id__gt: int | None = None,
+ id__gte: int | None = None,
+ id__lt: int | None = None,
+ id__lte: int | None = None,
+ id__between: tuple[int, int] | None = None,
+ id__range: int | None = None,
+ id__in: list[int] | None = None,
+ id__isnull: bool | None = None,
+ relation: str | None = None,
+ relation__contains: str | None = None,
+ relation__icontains: str | None = None,
+ relation__startswith: str | None = None,
+ relation__istartswith: str | None = None,
+ relation__endswith: str | None = None,
+ relation__iendswith: str | None = None,
+ relation__iexact: str | None = None,
+ relation__in: list[str] | None = None,
+ relation__isnull: bool | None = None,
+ repo: GitRepo | None = None,
+ repo__in: list[GitRepo] | None = None,
+ repo__isnull: bool | None = None,
+ repo_id: int | None = None,
+ repo_id__gt: int | None = None,
+ repo_id__gte: int | None = None,
+ repo_id__lt: int | None = None,
+ repo_id__lte: int | None = None,
+ repo_id__between: tuple[int, int] | None = None,
+ repo_id__range: int | None = None,
+ repo_id__in: list[int] | None = None,
+ repo_id__isnull: bool | None = None,
+ task_id: int | None = None,
+ task_id__gt: int | None = None,
+ task_id__gte: int | None = None,
+ task_id__lt: int | None = None,
+ task_id__lte: int | None = None,
+ task_id__between: tuple[int, int] | None = None,
+ task_id__range: int | None = None,
+ task_id__in: list[int] | None = None,
+ task_id__isnull: bool | None = None,
+ ) -> "GitCommitTaskRefQuery":
+ """Filter by Q-expressions or field lookups."""
+ ...
+
+ def exclude(
+ self,
+ *args: Any,
+ commit_sha: str | None = None,
+ commit_sha__contains: str | None = None,
+ commit_sha__icontains: str | None = None,
+ commit_sha__startswith: str | None = None,
+ commit_sha__istartswith: str | None = None,
+ commit_sha__endswith: str | None = None,
+ commit_sha__iendswith: str | None = None,
+ commit_sha__iexact: str | None = None,
+ commit_sha__in: list[str] | None = None,
+ commit_sha__isnull: bool | None = None,
+ created_at: datetime | None = None,
+ created_at__gt: datetime | None = None,
+ created_at__gte: datetime | None = None,
+ created_at__lt: datetime | None = None,
+ created_at__lte: datetime | None = None,
+ created_at__between: tuple[datetime, datetime] | None = None,
+ created_at__range: datetime | None = None,
+ created_at__year: int | None = None,
+ created_at__month: int | None = None,
+ created_at__day: int | None = None,
+ created_at__in: list[datetime] | None = None,
+ created_at__isnull: bool | None = None,
+ id: int | None = None,
+ id__gt: int | None = None,
+ id__gte: int | None = None,
+ id__lt: int | None = None,
+ id__lte: int | None = None,
+ id__between: tuple[int, int] | None = None,
+ id__range: int | None = None,
+ id__in: list[int] | None = None,
+ id__isnull: bool | None = None,
+ relation: str | None = None,
+ relation__contains: str | None = None,
+ relation__icontains: str | None = None,
+ relation__startswith: str | None = None,
+ relation__istartswith: str | None = None,
+ relation__endswith: str | None = None,
+ relation__iendswith: str | None = None,
+ relation__iexact: str | None = None,
+ relation__in: list[str] | None = None,
+ relation__isnull: bool | None = None,
+ repo: GitRepo | None = None,
+ repo__in: list[GitRepo] | None = None,
+ repo__isnull: bool | None = None,
+ repo_id: int | None = None,
+ repo_id__gt: int | None = None,
+ repo_id__gte: int | None = None,
+ repo_id__lt: int | None = None,
+ repo_id__lte: int | None = None,
+ repo_id__between: tuple[int, int] | None = None,
+ repo_id__range: int | None = None,
+ repo_id__in: list[int] | None = None,
+ repo_id__isnull: bool | None = None,
+ task_id: int | None = None,
+ task_id__gt: int | None = None,
+ task_id__gte: int | None = None,
+ task_id__lt: int | None = None,
+ task_id__lte: int | None = None,
+ task_id__between: tuple[int, int] | None = None,
+ task_id__range: int | None = None,
+ task_id__in: list[int] | None = None,
+ task_id__isnull: bool | None = None,
+ ) -> "GitCommitTaskRefQuery":
+ """Exclude objects matching field lookups."""
+ ...
+
+ def order_by(self, *fields: Literal["commit_sha", "-commit_sha", "created_at", "-created_at", "id", "-id", "relation", "-relation", "repo", "-repo", "repo_id", "-repo_id", "task_id", "-task_id"]) -> "GitCommitTaskRefQuery": # type: ignore[override]
+ """Order results by fields."""
+ ...
+
+ def limit(self, n: int) -> "GitCommitTaskRefQuery":
+ """Limit number of results."""
+ ...
+
+ def offset(self, n: int) -> "GitCommitTaskRefQuery":
+ """Skip first n results."""
+ ...
+
+ def distinct(self, value: bool = True) -> "GitCommitTaskRefQuery":
+ """Return distinct results."""
+ ...
+
+ def select(self, *fields: Literal["commit_sha", "created_at", "id", "relation", "repo", "repo_id", "task_id"]) -> "GitCommitTaskRefQuery": # type: ignore[override]
+ """Select specific fields."""
+ ...
+
+ def join(self, *paths: str) -> "GitCommitTaskRefQuery":
+ """Perform LEFT JOIN for relations."""
+ ...
+
+ def prefetch(self, *paths: str) -> "GitCommitTaskRefQuery":
+ """Prefetch related objects (separate queries)."""
+ ...
+
+ def for_update(self) -> "GitCommitTaskRefQuery":
+ """Add FOR UPDATE lock to query."""
+ ...
+
+ def for_share(self) -> "GitCommitTaskRefQuery":
+ """Add FOR SHARE lock to query."""
+ ...
+
+ def annotate(self, **annotations: Any) -> "GitCommitTaskRefQuery":
+ """Add computed fields using aggregate functions."""
+ ...
+
+ def group_by(self, *fields: Literal["commit_sha", "created_at", "id", "relation", "repo", "repo_id", "task_id"]) -> "GitCommitTaskRefQuery": # type: ignore[override]
+ """Add GROUP BY clause."""
+ ...
+
+ def having(self, *q_exprs: Any, **kwargs: Any) -> "GitCommitTaskRefQuery":
+ """Add HAVING clause for filtering grouped results."""
+ ...
+
+ def values(self, *fields: Literal["commit_sha", "created_at", "id", "relation", "repo", "repo_id", "task_id"]) -> "GitCommitTaskRefQuery": # type: ignore[override]
+ """Return dicts instead of models."""
+ ...
+
+ def values_list(self, *fields: Literal["commit_sha", "created_at", "id", "relation", "repo", "repo_id", "task_id"], flat: bool = False) -> "GitCommitTaskRefQuery": # type: ignore[override]
+ """Return tuples/values instead of models."""
+ ...
+
+ # Terminal methods (async, execute query)
+
+ async def all(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> list[GitCommitTaskRef]:
+ """Execute query and return all results."""
+ ...
+
+ async def first(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> GitCommitTaskRef | None:
+ """Execute query and return first result."""
+ ...
+
+ async def last(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> GitCommitTaskRef | None:
+ """Execute query and return last result."""
+ ...
+
+ async def count(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> int:
+ """Count matching objects."""
+ ...
+
+ async def sum(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Calculate sum of field values."""
+ ...
+
+ async def avg(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Calculate average of field values."""
+ ...
+
+ async def max(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Get maximum field value."""
+ ...
+
+ async def min(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Get minimum field value."""
+ ...
+
+ async def update( # type: ignore[override]
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ **values: Any,
+ ) -> int:
+ """Update matching objects."""
+ ...
+
+ async def increment(
+ self,
+ field: str,
+ by: int | float = 1,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> int:
+ """Atomically increment a field value."""
+ ...
+
+ async def delete(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> int:
+ """Delete matching objects."""
+ ...
+
+class GitCommitTaskRefManager(QueryManager[GitCommitTaskRef]):
+ """Type-safe Manager for GitCommitTaskRef model."""
+
+ # Query building methods (sync, return Query)
+
+ def query(self) -> GitCommitTaskRefQuery:
+ """Return a Query builder for this model."""
+ ...
+
+ def filter(
+ self,
+ *args: Any,
+ commit_sha: str | None = None,
+ commit_sha__contains: str | None = None,
+ commit_sha__icontains: str | None = None,
+ commit_sha__startswith: str | None = None,
+ commit_sha__istartswith: str | None = None,
+ commit_sha__endswith: str | None = None,
+ commit_sha__iendswith: str | None = None,
+ commit_sha__iexact: str | None = None,
+ commit_sha__in: list[str] | None = None,
+ commit_sha__isnull: bool | None = None,
+ created_at: datetime | None = None,
+ created_at__gt: datetime | None = None,
+ created_at__gte: datetime | None = None,
+ created_at__lt: datetime | None = None,
+ created_at__lte: datetime | None = None,
+ created_at__between: tuple[datetime, datetime] | None = None,
+ created_at__range: datetime | None = None,
+ created_at__year: int | None = None,
+ created_at__month: int | None = None,
+ created_at__day: int | None = None,
+ created_at__in: list[datetime] | None = None,
+ created_at__isnull: bool | None = None,
+ id: int | None = None,
+ id__gt: int | None = None,
+ id__gte: int | None = None,
+ id__lt: int | None = None,
+ id__lte: int | None = None,
+ id__between: tuple[int, int] | None = None,
+ id__range: int | None = None,
+ id__in: list[int] | None = None,
+ id__isnull: bool | None = None,
+ relation: str | None = None,
+ relation__contains: str | None = None,
+ relation__icontains: str | None = None,
+ relation__startswith: str | None = None,
+ relation__istartswith: str | None = None,
+ relation__endswith: str | None = None,
+ relation__iendswith: str | None = None,
+ relation__iexact: str | None = None,
+ relation__in: list[str] | None = None,
+ relation__isnull: bool | None = None,
+ repo: GitRepo | None = None,
+ repo__in: list[GitRepo] | None = None,
+ repo__isnull: bool | None = None,
+ repo_id: int | None = None,
+ repo_id__gt: int | None = None,
+ repo_id__gte: int | None = None,
+ repo_id__lt: int | None = None,
+ repo_id__lte: int | None = None,
+ repo_id__between: tuple[int, int] | None = None,
+ repo_id__range: int | None = None,
+ repo_id__in: list[int] | None = None,
+ repo_id__isnull: bool | None = None,
+ task_id: int | None = None,
+ task_id__gt: int | None = None,
+ task_id__gte: int | None = None,
+ task_id__lt: int | None = None,
+ task_id__lte: int | None = None,
+ task_id__between: tuple[int, int] | None = None,
+ task_id__range: int | None = None,
+ task_id__in: list[int] | None = None,
+ task_id__isnull: bool | None = None,
+ ) -> GitCommitTaskRefQuery:
+ """Filter by Q-expressions or field lookups."""
+ ...
+
+ def exclude(
+ self,
+ *args: Any,
+ commit_sha: str | None = None,
+ commit_sha__contains: str | None = None,
+ commit_sha__icontains: str | None = None,
+ commit_sha__startswith: str | None = None,
+ commit_sha__istartswith: str | None = None,
+ commit_sha__endswith: str | None = None,
+ commit_sha__iendswith: str | None = None,
+ commit_sha__iexact: str | None = None,
+ commit_sha__in: list[str] | None = None,
+ commit_sha__isnull: bool | None = None,
+ created_at: datetime | None = None,
+ created_at__gt: datetime | None = None,
+ created_at__gte: datetime | None = None,
+ created_at__lt: datetime | None = None,
+ created_at__lte: datetime | None = None,
+ created_at__between: tuple[datetime, datetime] | None = None,
+ created_at__range: datetime | None = None,
+ created_at__year: int | None = None,
+ created_at__month: int | None = None,
+ created_at__day: int | None = None,
+ created_at__in: list[datetime] | None = None,
+ created_at__isnull: bool | None = None,
+ id: int | None = None,
+ id__gt: int | None = None,
+ id__gte: int | None = None,
+ id__lt: int | None = None,
+ id__lte: int | None = None,
+ id__between: tuple[int, int] | None = None,
+ id__range: int | None = None,
+ id__in: list[int] | None = None,
+ id__isnull: bool | None = None,
+ relation: str | None = None,
+ relation__contains: str | None = None,
+ relation__icontains: str | None = None,
+ relation__startswith: str | None = None,
+ relation__istartswith: str | None = None,
+ relation__endswith: str | None = None,
+ relation__iendswith: str | None = None,
+ relation__iexact: str | None = None,
+ relation__in: list[str] | None = None,
+ relation__isnull: bool | None = None,
+ repo: GitRepo | None = None,
+ repo__in: list[GitRepo] | None = None,
+ repo__isnull: bool | None = None,
+ repo_id: int | None = None,
+ repo_id__gt: int | None = None,
+ repo_id__gte: int | None = None,
+ repo_id__lt: int | None = None,
+ repo_id__lte: int | None = None,
+ repo_id__between: tuple[int, int] | None = None,
+ repo_id__range: int | None = None,
+ repo_id__in: list[int] | None = None,
+ repo_id__isnull: bool | None = None,
+ task_id: int | None = None,
+ task_id__gt: int | None = None,
+ task_id__gte: int | None = None,
+ task_id__lt: int | None = None,
+ task_id__lte: int | None = None,
+ task_id__between: tuple[int, int] | None = None,
+ task_id__range: int | None = None,
+ task_id__in: list[int] | None = None,
+ task_id__isnull: bool | None = None,
+ ) -> GitCommitTaskRefQuery:
+ """Exclude objects matching field lookups."""
+ ...
+
+ def values(self, *fields: Literal["commit_sha", "created_at", "id", "relation", "repo", "repo_id", "task_id"]) -> GitCommitTaskRefQuery: # type: ignore[override]
+ """Return dicts instead of models."""
+ ...
+
+ def values_list(self, *fields: Literal["commit_sha", "created_at", "id", "relation", "repo", "repo_id", "task_id"], flat: bool = False) -> GitCommitTaskRefQuery: # type: ignore[override]
+ """Return tuples/values instead of models."""
+ ...
+
+ def distinct(self, distinct: bool = True) -> GitCommitTaskRefQuery:
+ """Return distinct results."""
+ ...
+
+ def join(self, *paths: str) -> GitCommitTaskRefQuery:
+ """Perform LEFT JOIN for relations."""
+ ...
+
+ def prefetch(self, *paths: str) -> GitCommitTaskRefQuery:
+ """Prefetch related objects (separate queries)."""
+ ...
+
+ def for_update(self) -> GitCommitTaskRefQuery:
+ """Add FOR UPDATE lock to query."""
+ ...
+
+ def for_share(self) -> GitCommitTaskRefQuery:
+ """Add FOR SHARE lock to query."""
+ ...
+
+ # Terminal methods (async, execute query)
+
+ async def get(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ **filters: Any,
+ ) -> GitCommitTaskRef:
+ """Get single object matching lookups."""
+ ...
+
+ async def get_or_none(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ **filters: Any,
+ ) -> GitCommitTaskRef | None:
+ """Get object or None if not found."""
+ ...
+
+ async def get_or_create(
+ self,
+ *,
+ defaults: dict[str, Any] | None = None,
+ client: Any | None = None,
+ using: str | None = None,
+ **filters: Any,
+ ) -> tuple[GitCommitTaskRef, bool]:
+ """Get object or create if not found. Returns (object, created)."""
+ ...
+
+ async def update_or_create(
+ self,
+ *,
+ defaults: dict[str, Any] | None = None,
+ client: Any | None = None,
+ using: str | None = None,
+ **filters: Any,
+ ) -> tuple[GitCommitTaskRef, bool]:
+ """Get object, create if missing, or update it when defaults are provided."""
+ ...
+
+ async def all(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ mode: str = "models",
+ ) -> list[GitCommitTaskRef]:
+ """Get all objects."""
+ ...
+
+ async def first(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> GitCommitTaskRef | None:
+ """Get first object."""
+ ...
+
+ async def last(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> GitCommitTaskRef | None:
+ """Get last object."""
+ ...
+
+ async def count(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> int:
+ """Count all objects."""
+ ...
+
+ async def sum(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Calculate sum of field values."""
+ ...
+
+ async def avg(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Calculate average of field values."""
+ ...
+
+ async def max(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Get maximum field value."""
+ ...
+
+ async def min(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Get minimum field value."""
+ ...
+
+ async def create( # type: ignore[override]
+ self,
+ *,
+ instance: GitCommitTaskRef | None = None,
+ client: Any | None = None,
+ using: str | None = None,
+ commit_sha: str | None = None,
+ created_at: datetime | None = None,
+ id: int | None = None,
+ relation: str | None = None,
+ repo: GitRepo | None = None,
+ repo_id: int | None = None,
+ task_id: int | None = None,
+ ) -> GitCommitTaskRef:
+ """Create new object."""
+ ...
+
+ async def bulk_create( # type: ignore[override]
+ self,
+ objects: list[GitCommitTaskRef],
+ *,
+ batch_size: int | None = None,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> list[GitCommitTaskRef]:
+ """Bulk create objects."""
+ ...
+
+ async def bulk_update( # type: ignore[override]
+ self,
+ objects: list[GitCommitTaskRef],
+ fields: list[str],
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> int:
+ """Bulk update objects."""
+ ...
+
diff --git a/freenit/models/sql/lms.pyi b/freenit/models/sql/lms.pyi
new file mode 100644
index 0000000..563ee4b
--- /dev/null
+++ b/freenit/models/sql/lms.pyi
@@ -0,0 +1,3190 @@
+# Auto-generated by oxyde generate-stubs
+# DO NOT EDIT - This file will be overwritten
+
+from typing import Any, ClassVar, Literal
+from datetime import datetime, date, time
+from decimal import Decimal
+from uuid import UUID
+
+from oxyde import Model
+from oxyde.queries import Query, QueryManager
+
+from __future__ import annotations
+from datetime import datetime
+from enum import StrEnum
+import oxyde
+import pydantic
+from freenit.models.sql.base import OxydeBaseModel, User
+
+class Course(Model):
+ class Meta:
+ is_table: bool
+ table_name: str
+ id: int | None
+ name: str
+ description: str | None
+ created_by: User | None
+ created_at: datetime | None
+ updated_at: datetime | None
+ created_by_id: int | None
+ objects: ClassVar["CourseManager"]
+
+
+class CourseQuery(Query[Course]):
+ """Type-safe Query for Course model."""
+
+ # Query building methods (sync, return Query)
+
+ def filter(
+ self,
+ *args: Any,
+ created_at: datetime | None = None,
+ created_at__gt: datetime | None = None,
+ created_at__gte: datetime | None = None,
+ created_at__lt: datetime | None = None,
+ created_at__lte: datetime | None = None,
+ created_at__between: tuple[datetime, datetime] | None = None,
+ created_at__range: datetime | None = None,
+ created_at__year: int | None = None,
+ created_at__month: int | None = None,
+ created_at__day: int | None = None,
+ created_at__in: list[datetime] | None = None,
+ created_at__isnull: bool | None = None,
+ created_by: User | None = None,
+ created_by__in: list[User] | None = None,
+ created_by__isnull: bool | None = None,
+ created_by_id: int | None = None,
+ created_by_id__gt: int | None = None,
+ created_by_id__gte: int | None = None,
+ created_by_id__lt: int | None = None,
+ created_by_id__lte: int | None = None,
+ created_by_id__between: tuple[int, int] | None = None,
+ created_by_id__range: int | None = None,
+ created_by_id__in: list[int] | None = None,
+ created_by_id__isnull: bool | None = None,
+ description: str | None = None,
+ description__contains: str | None = None,
+ description__icontains: str | None = None,
+ description__startswith: str | None = None,
+ description__istartswith: str | None = None,
+ description__endswith: str | None = None,
+ description__iendswith: str | None = None,
+ description__iexact: str | None = None,
+ description__in: list[str] | None = None,
+ description__isnull: bool | None = None,
+ id: int | None = None,
+ id__gt: int | None = None,
+ id__gte: int | None = None,
+ id__lt: int | None = None,
+ id__lte: int | None = None,
+ id__between: tuple[int, int] | None = None,
+ id__range: int | None = None,
+ id__in: list[int] | None = None,
+ id__isnull: bool | None = None,
+ name: str | None = None,
+ name__contains: str | None = None,
+ name__icontains: str | None = None,
+ name__startswith: str | None = None,
+ name__istartswith: str | None = None,
+ name__endswith: str | None = None,
+ name__iendswith: str | None = None,
+ name__iexact: str | None = None,
+ name__in: list[str] | None = None,
+ name__isnull: bool | None = None,
+ updated_at: datetime | None = None,
+ updated_at__gt: datetime | None = None,
+ updated_at__gte: datetime | None = None,
+ updated_at__lt: datetime | None = None,
+ updated_at__lte: datetime | None = None,
+ updated_at__between: tuple[datetime, datetime] | None = None,
+ updated_at__range: datetime | None = None,
+ updated_at__year: int | None = None,
+ updated_at__month: int | None = None,
+ updated_at__day: int | None = None,
+ updated_at__in: list[datetime] | None = None,
+ updated_at__isnull: bool | None = None,
+ ) -> "CourseQuery":
+ """Filter by Q-expressions or field lookups."""
+ ...
+
+ def exclude(
+ self,
+ *args: Any,
+ created_at: datetime | None = None,
+ created_at__gt: datetime | None = None,
+ created_at__gte: datetime | None = None,
+ created_at__lt: datetime | None = None,
+ created_at__lte: datetime | None = None,
+ created_at__between: tuple[datetime, datetime] | None = None,
+ created_at__range: datetime | None = None,
+ created_at__year: int | None = None,
+ created_at__month: int | None = None,
+ created_at__day: int | None = None,
+ created_at__in: list[datetime] | None = None,
+ created_at__isnull: bool | None = None,
+ created_by: User | None = None,
+ created_by__in: list[User] | None = None,
+ created_by__isnull: bool | None = None,
+ created_by_id: int | None = None,
+ created_by_id__gt: int | None = None,
+ created_by_id__gte: int | None = None,
+ created_by_id__lt: int | None = None,
+ created_by_id__lte: int | None = None,
+ created_by_id__between: tuple[int, int] | None = None,
+ created_by_id__range: int | None = None,
+ created_by_id__in: list[int] | None = None,
+ created_by_id__isnull: bool | None = None,
+ description: str | None = None,
+ description__contains: str | None = None,
+ description__icontains: str | None = None,
+ description__startswith: str | None = None,
+ description__istartswith: str | None = None,
+ description__endswith: str | None = None,
+ description__iendswith: str | None = None,
+ description__iexact: str | None = None,
+ description__in: list[str] | None = None,
+ description__isnull: bool | None = None,
+ id: int | None = None,
+ id__gt: int | None = None,
+ id__gte: int | None = None,
+ id__lt: int | None = None,
+ id__lte: int | None = None,
+ id__between: tuple[int, int] | None = None,
+ id__range: int | None = None,
+ id__in: list[int] | None = None,
+ id__isnull: bool | None = None,
+ name: str | None = None,
+ name__contains: str | None = None,
+ name__icontains: str | None = None,
+ name__startswith: str | None = None,
+ name__istartswith: str | None = None,
+ name__endswith: str | None = None,
+ name__iendswith: str | None = None,
+ name__iexact: str | None = None,
+ name__in: list[str] | None = None,
+ name__isnull: bool | None = None,
+ updated_at: datetime | None = None,
+ updated_at__gt: datetime | None = None,
+ updated_at__gte: datetime | None = None,
+ updated_at__lt: datetime | None = None,
+ updated_at__lte: datetime | None = None,
+ updated_at__between: tuple[datetime, datetime] | None = None,
+ updated_at__range: datetime | None = None,
+ updated_at__year: int | None = None,
+ updated_at__month: int | None = None,
+ updated_at__day: int | None = None,
+ updated_at__in: list[datetime] | None = None,
+ updated_at__isnull: bool | None = None,
+ ) -> "CourseQuery":
+ """Exclude objects matching field lookups."""
+ ...
+
+ def order_by(self, *fields: Literal["created_at", "-created_at", "created_by", "-created_by", "created_by_id", "-created_by_id", "description", "-description", "id", "-id", "name", "-name", "updated_at", "-updated_at"]) -> "CourseQuery": # type: ignore[override]
+ """Order results by fields."""
+ ...
+
+ def limit(self, n: int) -> "CourseQuery":
+ """Limit number of results."""
+ ...
+
+ def offset(self, n: int) -> "CourseQuery":
+ """Skip first n results."""
+ ...
+
+ def distinct(self, value: bool = True) -> "CourseQuery":
+ """Return distinct results."""
+ ...
+
+ def select(self, *fields: Literal["created_at", "created_by", "created_by_id", "description", "id", "name", "updated_at"]) -> "CourseQuery": # type: ignore[override]
+ """Select specific fields."""
+ ...
+
+ def join(self, *paths: str) -> "CourseQuery":
+ """Perform LEFT JOIN for relations."""
+ ...
+
+ def prefetch(self, *paths: str) -> "CourseQuery":
+ """Prefetch related objects (separate queries)."""
+ ...
+
+ def for_update(self) -> "CourseQuery":
+ """Add FOR UPDATE lock to query."""
+ ...
+
+ def for_share(self) -> "CourseQuery":
+ """Add FOR SHARE lock to query."""
+ ...
+
+ def annotate(self, **annotations: Any) -> "CourseQuery":
+ """Add computed fields using aggregate functions."""
+ ...
+
+ def group_by(self, *fields: Literal["created_at", "created_by", "created_by_id", "description", "id", "name", "updated_at"]) -> "CourseQuery": # type: ignore[override]
+ """Add GROUP BY clause."""
+ ...
+
+ def having(self, *q_exprs: Any, **kwargs: Any) -> "CourseQuery":
+ """Add HAVING clause for filtering grouped results."""
+ ...
+
+ def values(self, *fields: Literal["created_at", "created_by", "created_by_id", "description", "id", "name", "updated_at"]) -> "CourseQuery": # type: ignore[override]
+ """Return dicts instead of models."""
+ ...
+
+ def values_list(self, *fields: Literal["created_at", "created_by", "created_by_id", "description", "id", "name", "updated_at"], flat: bool = False) -> "CourseQuery": # type: ignore[override]
+ """Return tuples/values instead of models."""
+ ...
+
+ # Terminal methods (async, execute query)
+
+ async def all(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> list[Course]:
+ """Execute query and return all results."""
+ ...
+
+ async def first(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Course | None:
+ """Execute query and return first result."""
+ ...
+
+ async def last(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Course | None:
+ """Execute query and return last result."""
+ ...
+
+ async def count(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> int:
+ """Count matching objects."""
+ ...
+
+ async def sum(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Calculate sum of field values."""
+ ...
+
+ async def avg(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Calculate average of field values."""
+ ...
+
+ async def max(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Get maximum field value."""
+ ...
+
+ async def min(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Get minimum field value."""
+ ...
+
+ async def update( # type: ignore[override]
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ **values: Any,
+ ) -> int:
+ """Update matching objects."""
+ ...
+
+ async def increment(
+ self,
+ field: str,
+ by: int | float = 1,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> int:
+ """Atomically increment a field value."""
+ ...
+
+ async def delete(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> int:
+ """Delete matching objects."""
+ ...
+
+class CourseManager(QueryManager[Course]):
+ """Type-safe Manager for Course model."""
+
+ # Query building methods (sync, return Query)
+
+ def query(self) -> CourseQuery:
+ """Return a Query builder for this model."""
+ ...
+
+ def filter(
+ self,
+ *args: Any,
+ created_at: datetime | None = None,
+ created_at__gt: datetime | None = None,
+ created_at__gte: datetime | None = None,
+ created_at__lt: datetime | None = None,
+ created_at__lte: datetime | None = None,
+ created_at__between: tuple[datetime, datetime] | None = None,
+ created_at__range: datetime | None = None,
+ created_at__year: int | None = None,
+ created_at__month: int | None = None,
+ created_at__day: int | None = None,
+ created_at__in: list[datetime] | None = None,
+ created_at__isnull: bool | None = None,
+ created_by: User | None = None,
+ created_by__in: list[User] | None = None,
+ created_by__isnull: bool | None = None,
+ created_by_id: int | None = None,
+ created_by_id__gt: int | None = None,
+ created_by_id__gte: int | None = None,
+ created_by_id__lt: int | None = None,
+ created_by_id__lte: int | None = None,
+ created_by_id__between: tuple[int, int] | None = None,
+ created_by_id__range: int | None = None,
+ created_by_id__in: list[int] | None = None,
+ created_by_id__isnull: bool | None = None,
+ description: str | None = None,
+ description__contains: str | None = None,
+ description__icontains: str | None = None,
+ description__startswith: str | None = None,
+ description__istartswith: str | None = None,
+ description__endswith: str | None = None,
+ description__iendswith: str | None = None,
+ description__iexact: str | None = None,
+ description__in: list[str] | None = None,
+ description__isnull: bool | None = None,
+ id: int | None = None,
+ id__gt: int | None = None,
+ id__gte: int | None = None,
+ id__lt: int | None = None,
+ id__lte: int | None = None,
+ id__between: tuple[int, int] | None = None,
+ id__range: int | None = None,
+ id__in: list[int] | None = None,
+ id__isnull: bool | None = None,
+ name: str | None = None,
+ name__contains: str | None = None,
+ name__icontains: str | None = None,
+ name__startswith: str | None = None,
+ name__istartswith: str | None = None,
+ name__endswith: str | None = None,
+ name__iendswith: str | None = None,
+ name__iexact: str | None = None,
+ name__in: list[str] | None = None,
+ name__isnull: bool | None = None,
+ updated_at: datetime | None = None,
+ updated_at__gt: datetime | None = None,
+ updated_at__gte: datetime | None = None,
+ updated_at__lt: datetime | None = None,
+ updated_at__lte: datetime | None = None,
+ updated_at__between: tuple[datetime, datetime] | None = None,
+ updated_at__range: datetime | None = None,
+ updated_at__year: int | None = None,
+ updated_at__month: int | None = None,
+ updated_at__day: int | None = None,
+ updated_at__in: list[datetime] | None = None,
+ updated_at__isnull: bool | None = None,
+ ) -> CourseQuery:
+ """Filter by Q-expressions or field lookups."""
+ ...
+
+ def exclude(
+ self,
+ *args: Any,
+ created_at: datetime | None = None,
+ created_at__gt: datetime | None = None,
+ created_at__gte: datetime | None = None,
+ created_at__lt: datetime | None = None,
+ created_at__lte: datetime | None = None,
+ created_at__between: tuple[datetime, datetime] | None = None,
+ created_at__range: datetime | None = None,
+ created_at__year: int | None = None,
+ created_at__month: int | None = None,
+ created_at__day: int | None = None,
+ created_at__in: list[datetime] | None = None,
+ created_at__isnull: bool | None = None,
+ created_by: User | None = None,
+ created_by__in: list[User] | None = None,
+ created_by__isnull: bool | None = None,
+ created_by_id: int | None = None,
+ created_by_id__gt: int | None = None,
+ created_by_id__gte: int | None = None,
+ created_by_id__lt: int | None = None,
+ created_by_id__lte: int | None = None,
+ created_by_id__between: tuple[int, int] | None = None,
+ created_by_id__range: int | None = None,
+ created_by_id__in: list[int] | None = None,
+ created_by_id__isnull: bool | None = None,
+ description: str | None = None,
+ description__contains: str | None = None,
+ description__icontains: str | None = None,
+ description__startswith: str | None = None,
+ description__istartswith: str | None = None,
+ description__endswith: str | None = None,
+ description__iendswith: str | None = None,
+ description__iexact: str | None = None,
+ description__in: list[str] | None = None,
+ description__isnull: bool | None = None,
+ id: int | None = None,
+ id__gt: int | None = None,
+ id__gte: int | None = None,
+ id__lt: int | None = None,
+ id__lte: int | None = None,
+ id__between: tuple[int, int] | None = None,
+ id__range: int | None = None,
+ id__in: list[int] | None = None,
+ id__isnull: bool | None = None,
+ name: str | None = None,
+ name__contains: str | None = None,
+ name__icontains: str | None = None,
+ name__startswith: str | None = None,
+ name__istartswith: str | None = None,
+ name__endswith: str | None = None,
+ name__iendswith: str | None = None,
+ name__iexact: str | None = None,
+ name__in: list[str] | None = None,
+ name__isnull: bool | None = None,
+ updated_at: datetime | None = None,
+ updated_at__gt: datetime | None = None,
+ updated_at__gte: datetime | None = None,
+ updated_at__lt: datetime | None = None,
+ updated_at__lte: datetime | None = None,
+ updated_at__between: tuple[datetime, datetime] | None = None,
+ updated_at__range: datetime | None = None,
+ updated_at__year: int | None = None,
+ updated_at__month: int | None = None,
+ updated_at__day: int | None = None,
+ updated_at__in: list[datetime] | None = None,
+ updated_at__isnull: bool | None = None,
+ ) -> CourseQuery:
+ """Exclude objects matching field lookups."""
+ ...
+
+ def values(self, *fields: Literal["created_at", "created_by", "created_by_id", "description", "id", "name", "updated_at"]) -> CourseQuery: # type: ignore[override]
+ """Return dicts instead of models."""
+ ...
+
+ def values_list(self, *fields: Literal["created_at", "created_by", "created_by_id", "description", "id", "name", "updated_at"], flat: bool = False) -> CourseQuery: # type: ignore[override]
+ """Return tuples/values instead of models."""
+ ...
+
+ def distinct(self, distinct: bool = True) -> CourseQuery:
+ """Return distinct results."""
+ ...
+
+ def join(self, *paths: str) -> CourseQuery:
+ """Perform LEFT JOIN for relations."""
+ ...
+
+ def prefetch(self, *paths: str) -> CourseQuery:
+ """Prefetch related objects (separate queries)."""
+ ...
+
+ def for_update(self) -> CourseQuery:
+ """Add FOR UPDATE lock to query."""
+ ...
+
+ def for_share(self) -> CourseQuery:
+ """Add FOR SHARE lock to query."""
+ ...
+
+ # Terminal methods (async, execute query)
+
+ async def get(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ **filters: Any,
+ ) -> Course:
+ """Get single object matching lookups."""
+ ...
+
+ async def get_or_none(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ **filters: Any,
+ ) -> Course | None:
+ """Get object or None if not found."""
+ ...
+
+ async def get_or_create(
+ self,
+ *,
+ defaults: dict[str, Any] | None = None,
+ client: Any | None = None,
+ using: str | None = None,
+ **filters: Any,
+ ) -> tuple[Course, bool]:
+ """Get object or create if not found. Returns (object, created)."""
+ ...
+
+ async def update_or_create(
+ self,
+ *,
+ defaults: dict[str, Any] | None = None,
+ client: Any | None = None,
+ using: str | None = None,
+ **filters: Any,
+ ) -> tuple[Course, bool]:
+ """Get object, create if missing, or update it when defaults are provided."""
+ ...
+
+ async def all(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ mode: str = "models",
+ ) -> list[Course]:
+ """Get all objects."""
+ ...
+
+ async def first(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Course | None:
+ """Get first object."""
+ ...
+
+ async def last(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Course | None:
+ """Get last object."""
+ ...
+
+ async def count(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> int:
+ """Count all objects."""
+ ...
+
+ async def sum(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Calculate sum of field values."""
+ ...
+
+ async def avg(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Calculate average of field values."""
+ ...
+
+ async def max(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Get maximum field value."""
+ ...
+
+ async def min(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Get minimum field value."""
+ ...
+
+ async def create( # type: ignore[override]
+ self,
+ *,
+ instance: Course | None = None,
+ client: Any | None = None,
+ using: str | None = None,
+ created_at: datetime | None = None,
+ created_by: User | None = None,
+ created_by_id: int | None = None,
+ description: str | None = None,
+ id: int | None = None,
+ name: str | None = None,
+ updated_at: datetime | None = None,
+ ) -> Course:
+ """Create new object."""
+ ...
+
+ async def bulk_create( # type: ignore[override]
+ self,
+ objects: list[Course],
+ *,
+ batch_size: int | None = None,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> list[Course]:
+ """Bulk create objects."""
+ ...
+
+ async def bulk_update( # type: ignore[override]
+ self,
+ objects: list[Course],
+ fields: list[str],
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> int:
+ """Bulk update objects."""
+ ...
+
+
+class Lecture(Model):
+ class Meta:
+ is_table: bool
+ table_name: str
+ id: int | None
+ course: Course | None
+ title: str
+ content: str | None
+ position: int
+ state: LectureState
+ created_at: datetime | None
+ updated_at: datetime | None
+ course_id: int | None
+ objects: ClassVar["LectureManager"]
+
+
+class LectureQuery(Query[Lecture]):
+ """Type-safe Query for Lecture model."""
+
+ # Query building methods (sync, return Query)
+
+ def filter(
+ self,
+ *args: Any,
+ content: str | None = None,
+ content__contains: str | None = None,
+ content__icontains: str | None = None,
+ content__startswith: str | None = None,
+ content__istartswith: str | None = None,
+ content__endswith: str | None = None,
+ content__iendswith: str | None = None,
+ content__iexact: str | None = None,
+ content__in: list[str] | None = None,
+ content__isnull: bool | None = None,
+ course: Course | None = None,
+ course__in: list[Course] | None = None,
+ course__isnull: bool | None = None,
+ course_id: int | None = None,
+ course_id__gt: int | None = None,
+ course_id__gte: int | None = None,
+ course_id__lt: int | None = None,
+ course_id__lte: int | None = None,
+ course_id__between: tuple[int, int] | None = None,
+ course_id__range: int | None = None,
+ course_id__in: list[int] | None = None,
+ course_id__isnull: bool | None = None,
+ created_at: datetime | None = None,
+ created_at__gt: datetime | None = None,
+ created_at__gte: datetime | None = None,
+ created_at__lt: datetime | None = None,
+ created_at__lte: datetime | None = None,
+ created_at__between: tuple[datetime, datetime] | None = None,
+ created_at__range: datetime | None = None,
+ created_at__year: int | None = None,
+ created_at__month: int | None = None,
+ created_at__day: int | None = None,
+ created_at__in: list[datetime] | None = None,
+ created_at__isnull: bool | None = None,
+ id: int | None = None,
+ id__gt: int | None = None,
+ id__gte: int | None = None,
+ id__lt: int | None = None,
+ id__lte: int | None = None,
+ id__between: tuple[int, int] | None = None,
+ id__range: int | None = None,
+ id__in: list[int] | None = None,
+ id__isnull: bool | None = None,
+ position: int | None = None,
+ position__gt: int | None = None,
+ position__gte: int | None = None,
+ position__lt: int | None = None,
+ position__lte: int | None = None,
+ position__between: tuple[int, int] | None = None,
+ position__range: int | None = None,
+ position__in: list[int] | None = None,
+ position__isnull: bool | None = None,
+ state: LectureState | None = None,
+ state__in: list[LectureState] | None = None,
+ state__isnull: bool | None = None,
+ title: str | None = None,
+ title__contains: str | None = None,
+ title__icontains: str | None = None,
+ title__startswith: str | None = None,
+ title__istartswith: str | None = None,
+ title__endswith: str | None = None,
+ title__iendswith: str | None = None,
+ title__iexact: str | None = None,
+ title__in: list[str] | None = None,
+ title__isnull: bool | None = None,
+ updated_at: datetime | None = None,
+ updated_at__gt: datetime | None = None,
+ updated_at__gte: datetime | None = None,
+ updated_at__lt: datetime | None = None,
+ updated_at__lte: datetime | None = None,
+ updated_at__between: tuple[datetime, datetime] | None = None,
+ updated_at__range: datetime | None = None,
+ updated_at__year: int | None = None,
+ updated_at__month: int | None = None,
+ updated_at__day: int | None = None,
+ updated_at__in: list[datetime] | None = None,
+ updated_at__isnull: bool | None = None,
+ ) -> "LectureQuery":
+ """Filter by Q-expressions or field lookups."""
+ ...
+
+ def exclude(
+ self,
+ *args: Any,
+ content: str | None = None,
+ content__contains: str | None = None,
+ content__icontains: str | None = None,
+ content__startswith: str | None = None,
+ content__istartswith: str | None = None,
+ content__endswith: str | None = None,
+ content__iendswith: str | None = None,
+ content__iexact: str | None = None,
+ content__in: list[str] | None = None,
+ content__isnull: bool | None = None,
+ course: Course | None = None,
+ course__in: list[Course] | None = None,
+ course__isnull: bool | None = None,
+ course_id: int | None = None,
+ course_id__gt: int | None = None,
+ course_id__gte: int | None = None,
+ course_id__lt: int | None = None,
+ course_id__lte: int | None = None,
+ course_id__between: tuple[int, int] | None = None,
+ course_id__range: int | None = None,
+ course_id__in: list[int] | None = None,
+ course_id__isnull: bool | None = None,
+ created_at: datetime | None = None,
+ created_at__gt: datetime | None = None,
+ created_at__gte: datetime | None = None,
+ created_at__lt: datetime | None = None,
+ created_at__lte: datetime | None = None,
+ created_at__between: tuple[datetime, datetime] | None = None,
+ created_at__range: datetime | None = None,
+ created_at__year: int | None = None,
+ created_at__month: int | None = None,
+ created_at__day: int | None = None,
+ created_at__in: list[datetime] | None = None,
+ created_at__isnull: bool | None = None,
+ id: int | None = None,
+ id__gt: int | None = None,
+ id__gte: int | None = None,
+ id__lt: int | None = None,
+ id__lte: int | None = None,
+ id__between: tuple[int, int] | None = None,
+ id__range: int | None = None,
+ id__in: list[int] | None = None,
+ id__isnull: bool | None = None,
+ position: int | None = None,
+ position__gt: int | None = None,
+ position__gte: int | None = None,
+ position__lt: int | None = None,
+ position__lte: int | None = None,
+ position__between: tuple[int, int] | None = None,
+ position__range: int | None = None,
+ position__in: list[int] | None = None,
+ position__isnull: bool | None = None,
+ state: LectureState | None = None,
+ state__in: list[LectureState] | None = None,
+ state__isnull: bool | None = None,
+ title: str | None = None,
+ title__contains: str | None = None,
+ title__icontains: str | None = None,
+ title__startswith: str | None = None,
+ title__istartswith: str | None = None,
+ title__endswith: str | None = None,
+ title__iendswith: str | None = None,
+ title__iexact: str | None = None,
+ title__in: list[str] | None = None,
+ title__isnull: bool | None = None,
+ updated_at: datetime | None = None,
+ updated_at__gt: datetime | None = None,
+ updated_at__gte: datetime | None = None,
+ updated_at__lt: datetime | None = None,
+ updated_at__lte: datetime | None = None,
+ updated_at__between: tuple[datetime, datetime] | None = None,
+ updated_at__range: datetime | None = None,
+ updated_at__year: int | None = None,
+ updated_at__month: int | None = None,
+ updated_at__day: int | None = None,
+ updated_at__in: list[datetime] | None = None,
+ updated_at__isnull: bool | None = None,
+ ) -> "LectureQuery":
+ """Exclude objects matching field lookups."""
+ ...
+
+ def order_by(self, *fields: Literal["content", "-content", "course", "-course", "course_id", "-course_id", "created_at", "-created_at", "id", "-id", "position", "-position", "state", "-state", "title", "-title", "updated_at", "-updated_at"]) -> "LectureQuery": # type: ignore[override]
+ """Order results by fields."""
+ ...
+
+ def limit(self, n: int) -> "LectureQuery":
+ """Limit number of results."""
+ ...
+
+ def offset(self, n: int) -> "LectureQuery":
+ """Skip first n results."""
+ ...
+
+ def distinct(self, value: bool = True) -> "LectureQuery":
+ """Return distinct results."""
+ ...
+
+ def select(self, *fields: Literal["content", "course", "course_id", "created_at", "id", "position", "state", "title", "updated_at"]) -> "LectureQuery": # type: ignore[override]
+ """Select specific fields."""
+ ...
+
+ def join(self, *paths: str) -> "LectureQuery":
+ """Perform LEFT JOIN for relations."""
+ ...
+
+ def prefetch(self, *paths: str) -> "LectureQuery":
+ """Prefetch related objects (separate queries)."""
+ ...
+
+ def for_update(self) -> "LectureQuery":
+ """Add FOR UPDATE lock to query."""
+ ...
+
+ def for_share(self) -> "LectureQuery":
+ """Add FOR SHARE lock to query."""
+ ...
+
+ def annotate(self, **annotations: Any) -> "LectureQuery":
+ """Add computed fields using aggregate functions."""
+ ...
+
+ def group_by(self, *fields: Literal["content", "course", "course_id", "created_at", "id", "position", "state", "title", "updated_at"]) -> "LectureQuery": # type: ignore[override]
+ """Add GROUP BY clause."""
+ ...
+
+ def having(self, *q_exprs: Any, **kwargs: Any) -> "LectureQuery":
+ """Add HAVING clause for filtering grouped results."""
+ ...
+
+ def values(self, *fields: Literal["content", "course", "course_id", "created_at", "id", "position", "state", "title", "updated_at"]) -> "LectureQuery": # type: ignore[override]
+ """Return dicts instead of models."""
+ ...
+
+ def values_list(self, *fields: Literal["content", "course", "course_id", "created_at", "id", "position", "state", "title", "updated_at"], flat: bool = False) -> "LectureQuery": # type: ignore[override]
+ """Return tuples/values instead of models."""
+ ...
+
+ # Terminal methods (async, execute query)
+
+ async def all(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> list[Lecture]:
+ """Execute query and return all results."""
+ ...
+
+ async def first(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Lecture | None:
+ """Execute query and return first result."""
+ ...
+
+ async def last(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Lecture | None:
+ """Execute query and return last result."""
+ ...
+
+ async def count(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> int:
+ """Count matching objects."""
+ ...
+
+ async def sum(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Calculate sum of field values."""
+ ...
+
+ async def avg(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Calculate average of field values."""
+ ...
+
+ async def max(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Get maximum field value."""
+ ...
+
+ async def min(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Get minimum field value."""
+ ...
+
+ async def update( # type: ignore[override]
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ **values: Any,
+ ) -> int:
+ """Update matching objects."""
+ ...
+
+ async def increment(
+ self,
+ field: str,
+ by: int | float = 1,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> int:
+ """Atomically increment a field value."""
+ ...
+
+ async def delete(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> int:
+ """Delete matching objects."""
+ ...
+
+class LectureManager(QueryManager[Lecture]):
+ """Type-safe Manager for Lecture model."""
+
+ # Query building methods (sync, return Query)
+
+ def query(self) -> LectureQuery:
+ """Return a Query builder for this model."""
+ ...
+
+ def filter(
+ self,
+ *args: Any,
+ content: str | None = None,
+ content__contains: str | None = None,
+ content__icontains: str | None = None,
+ content__startswith: str | None = None,
+ content__istartswith: str | None = None,
+ content__endswith: str | None = None,
+ content__iendswith: str | None = None,
+ content__iexact: str | None = None,
+ content__in: list[str] | None = None,
+ content__isnull: bool | None = None,
+ course: Course | None = None,
+ course__in: list[Course] | None = None,
+ course__isnull: bool | None = None,
+ course_id: int | None = None,
+ course_id__gt: int | None = None,
+ course_id__gte: int | None = None,
+ course_id__lt: int | None = None,
+ course_id__lte: int | None = None,
+ course_id__between: tuple[int, int] | None = None,
+ course_id__range: int | None = None,
+ course_id__in: list[int] | None = None,
+ course_id__isnull: bool | None = None,
+ created_at: datetime | None = None,
+ created_at__gt: datetime | None = None,
+ created_at__gte: datetime | None = None,
+ created_at__lt: datetime | None = None,
+ created_at__lte: datetime | None = None,
+ created_at__between: tuple[datetime, datetime] | None = None,
+ created_at__range: datetime | None = None,
+ created_at__year: int | None = None,
+ created_at__month: int | None = None,
+ created_at__day: int | None = None,
+ created_at__in: list[datetime] | None = None,
+ created_at__isnull: bool | None = None,
+ id: int | None = None,
+ id__gt: int | None = None,
+ id__gte: int | None = None,
+ id__lt: int | None = None,
+ id__lte: int | None = None,
+ id__between: tuple[int, int] | None = None,
+ id__range: int | None = None,
+ id__in: list[int] | None = None,
+ id__isnull: bool | None = None,
+ position: int | None = None,
+ position__gt: int | None = None,
+ position__gte: int | None = None,
+ position__lt: int | None = None,
+ position__lte: int | None = None,
+ position__between: tuple[int, int] | None = None,
+ position__range: int | None = None,
+ position__in: list[int] | None = None,
+ position__isnull: bool | None = None,
+ state: LectureState | None = None,
+ state__in: list[LectureState] | None = None,
+ state__isnull: bool | None = None,
+ title: str | None = None,
+ title__contains: str | None = None,
+ title__icontains: str | None = None,
+ title__startswith: str | None = None,
+ title__istartswith: str | None = None,
+ title__endswith: str | None = None,
+ title__iendswith: str | None = None,
+ title__iexact: str | None = None,
+ title__in: list[str] | None = None,
+ title__isnull: bool | None = None,
+ updated_at: datetime | None = None,
+ updated_at__gt: datetime | None = None,
+ updated_at__gte: datetime | None = None,
+ updated_at__lt: datetime | None = None,
+ updated_at__lte: datetime | None = None,
+ updated_at__between: tuple[datetime, datetime] | None = None,
+ updated_at__range: datetime | None = None,
+ updated_at__year: int | None = None,
+ updated_at__month: int | None = None,
+ updated_at__day: int | None = None,
+ updated_at__in: list[datetime] | None = None,
+ updated_at__isnull: bool | None = None,
+ ) -> LectureQuery:
+ """Filter by Q-expressions or field lookups."""
+ ...
+
+ def exclude(
+ self,
+ *args: Any,
+ content: str | None = None,
+ content__contains: str | None = None,
+ content__icontains: str | None = None,
+ content__startswith: str | None = None,
+ content__istartswith: str | None = None,
+ content__endswith: str | None = None,
+ content__iendswith: str | None = None,
+ content__iexact: str | None = None,
+ content__in: list[str] | None = None,
+ content__isnull: bool | None = None,
+ course: Course | None = None,
+ course__in: list[Course] | None = None,
+ course__isnull: bool | None = None,
+ course_id: int | None = None,
+ course_id__gt: int | None = None,
+ course_id__gte: int | None = None,
+ course_id__lt: int | None = None,
+ course_id__lte: int | None = None,
+ course_id__between: tuple[int, int] | None = None,
+ course_id__range: int | None = None,
+ course_id__in: list[int] | None = None,
+ course_id__isnull: bool | None = None,
+ created_at: datetime | None = None,
+ created_at__gt: datetime | None = None,
+ created_at__gte: datetime | None = None,
+ created_at__lt: datetime | None = None,
+ created_at__lte: datetime | None = None,
+ created_at__between: tuple[datetime, datetime] | None = None,
+ created_at__range: datetime | None = None,
+ created_at__year: int | None = None,
+ created_at__month: int | None = None,
+ created_at__day: int | None = None,
+ created_at__in: list[datetime] | None = None,
+ created_at__isnull: bool | None = None,
+ id: int | None = None,
+ id__gt: int | None = None,
+ id__gte: int | None = None,
+ id__lt: int | None = None,
+ id__lte: int | None = None,
+ id__between: tuple[int, int] | None = None,
+ id__range: int | None = None,
+ id__in: list[int] | None = None,
+ id__isnull: bool | None = None,
+ position: int | None = None,
+ position__gt: int | None = None,
+ position__gte: int | None = None,
+ position__lt: int | None = None,
+ position__lte: int | None = None,
+ position__between: tuple[int, int] | None = None,
+ position__range: int | None = None,
+ position__in: list[int] | None = None,
+ position__isnull: bool | None = None,
+ state: LectureState | None = None,
+ state__in: list[LectureState] | None = None,
+ state__isnull: bool | None = None,
+ title: str | None = None,
+ title__contains: str | None = None,
+ title__icontains: str | None = None,
+ title__startswith: str | None = None,
+ title__istartswith: str | None = None,
+ title__endswith: str | None = None,
+ title__iendswith: str | None = None,
+ title__iexact: str | None = None,
+ title__in: list[str] | None = None,
+ title__isnull: bool | None = None,
+ updated_at: datetime | None = None,
+ updated_at__gt: datetime | None = None,
+ updated_at__gte: datetime | None = None,
+ updated_at__lt: datetime | None = None,
+ updated_at__lte: datetime | None = None,
+ updated_at__between: tuple[datetime, datetime] | None = None,
+ updated_at__range: datetime | None = None,
+ updated_at__year: int | None = None,
+ updated_at__month: int | None = None,
+ updated_at__day: int | None = None,
+ updated_at__in: list[datetime] | None = None,
+ updated_at__isnull: bool | None = None,
+ ) -> LectureQuery:
+ """Exclude objects matching field lookups."""
+ ...
+
+ def values(self, *fields: Literal["content", "course", "course_id", "created_at", "id", "position", "state", "title", "updated_at"]) -> LectureQuery: # type: ignore[override]
+ """Return dicts instead of models."""
+ ...
+
+ def values_list(self, *fields: Literal["content", "course", "course_id", "created_at", "id", "position", "state", "title", "updated_at"], flat: bool = False) -> LectureQuery: # type: ignore[override]
+ """Return tuples/values instead of models."""
+ ...
+
+ def distinct(self, distinct: bool = True) -> LectureQuery:
+ """Return distinct results."""
+ ...
+
+ def join(self, *paths: str) -> LectureQuery:
+ """Perform LEFT JOIN for relations."""
+ ...
+
+ def prefetch(self, *paths: str) -> LectureQuery:
+ """Prefetch related objects (separate queries)."""
+ ...
+
+ def for_update(self) -> LectureQuery:
+ """Add FOR UPDATE lock to query."""
+ ...
+
+ def for_share(self) -> LectureQuery:
+ """Add FOR SHARE lock to query."""
+ ...
+
+ # Terminal methods (async, execute query)
+
+ async def get(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ **filters: Any,
+ ) -> Lecture:
+ """Get single object matching lookups."""
+ ...
+
+ async def get_or_none(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ **filters: Any,
+ ) -> Lecture | None:
+ """Get object or None if not found."""
+ ...
+
+ async def get_or_create(
+ self,
+ *,
+ defaults: dict[str, Any] | None = None,
+ client: Any | None = None,
+ using: str | None = None,
+ **filters: Any,
+ ) -> tuple[Lecture, bool]:
+ """Get object or create if not found. Returns (object, created)."""
+ ...
+
+ async def update_or_create(
+ self,
+ *,
+ defaults: dict[str, Any] | None = None,
+ client: Any | None = None,
+ using: str | None = None,
+ **filters: Any,
+ ) -> tuple[Lecture, bool]:
+ """Get object, create if missing, or update it when defaults are provided."""
+ ...
+
+ async def all(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ mode: str = "models",
+ ) -> list[Lecture]:
+ """Get all objects."""
+ ...
+
+ async def first(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Lecture | None:
+ """Get first object."""
+ ...
+
+ async def last(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Lecture | None:
+ """Get last object."""
+ ...
+
+ async def count(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> int:
+ """Count all objects."""
+ ...
+
+ async def sum(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Calculate sum of field values."""
+ ...
+
+ async def avg(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Calculate average of field values."""
+ ...
+
+ async def max(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Get maximum field value."""
+ ...
+
+ async def min(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Get minimum field value."""
+ ...
+
+ async def create( # type: ignore[override]
+ self,
+ *,
+ instance: Lecture | None = None,
+ client: Any | None = None,
+ using: str | None = None,
+ content: str | None = None,
+ course: Course | None = None,
+ course_id: int | None = None,
+ created_at: datetime | None = None,
+ id: int | None = None,
+ position: int | None = None,
+ state: LectureState | None = None,
+ title: str | None = None,
+ updated_at: datetime | None = None,
+ ) -> Lecture:
+ """Create new object."""
+ ...
+
+ async def bulk_create( # type: ignore[override]
+ self,
+ objects: list[Lecture],
+ *,
+ batch_size: int | None = None,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> list[Lecture]:
+ """Bulk create objects."""
+ ...
+
+ async def bulk_update( # type: ignore[override]
+ self,
+ objects: list[Lecture],
+ fields: list[str],
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> int:
+ """Bulk update objects."""
+ ...
+
+
+class CourseGroup(Model):
+ class Meta:
+ is_table: bool
+ table_name: str
+ id: int | None
+ course: Course | None
+ name: str
+ description: str | None
+ created_at: datetime | None
+ updated_at: datetime | None
+ course_id: int | None
+ objects: ClassVar["CourseGroupManager"]
+
+
+class CourseGroupQuery(Query[CourseGroup]):
+ """Type-safe Query for CourseGroup model."""
+
+ # Query building methods (sync, return Query)
+
+ def filter(
+ self,
+ *args: Any,
+ course: Course | None = None,
+ course__in: list[Course] | None = None,
+ course__isnull: bool | None = None,
+ course_id: int | None = None,
+ course_id__gt: int | None = None,
+ course_id__gte: int | None = None,
+ course_id__lt: int | None = None,
+ course_id__lte: int | None = None,
+ course_id__between: tuple[int, int] | None = None,
+ course_id__range: int | None = None,
+ course_id__in: list[int] | None = None,
+ course_id__isnull: bool | None = None,
+ created_at: datetime | None = None,
+ created_at__gt: datetime | None = None,
+ created_at__gte: datetime | None = None,
+ created_at__lt: datetime | None = None,
+ created_at__lte: datetime | None = None,
+ created_at__between: tuple[datetime, datetime] | None = None,
+ created_at__range: datetime | None = None,
+ created_at__year: int | None = None,
+ created_at__month: int | None = None,
+ created_at__day: int | None = None,
+ created_at__in: list[datetime] | None = None,
+ created_at__isnull: bool | None = None,
+ description: str | None = None,
+ description__contains: str | None = None,
+ description__icontains: str | None = None,
+ description__startswith: str | None = None,
+ description__istartswith: str | None = None,
+ description__endswith: str | None = None,
+ description__iendswith: str | None = None,
+ description__iexact: str | None = None,
+ description__in: list[str] | None = None,
+ description__isnull: bool | None = None,
+ id: int | None = None,
+ id__gt: int | None = None,
+ id__gte: int | None = None,
+ id__lt: int | None = None,
+ id__lte: int | None = None,
+ id__between: tuple[int, int] | None = None,
+ id__range: int | None = None,
+ id__in: list[int] | None = None,
+ id__isnull: bool | None = None,
+ name: str | None = None,
+ name__contains: str | None = None,
+ name__icontains: str | None = None,
+ name__startswith: str | None = None,
+ name__istartswith: str | None = None,
+ name__endswith: str | None = None,
+ name__iendswith: str | None = None,
+ name__iexact: str | None = None,
+ name__in: list[str] | None = None,
+ name__isnull: bool | None = None,
+ updated_at: datetime | None = None,
+ updated_at__gt: datetime | None = None,
+ updated_at__gte: datetime | None = None,
+ updated_at__lt: datetime | None = None,
+ updated_at__lte: datetime | None = None,
+ updated_at__between: tuple[datetime, datetime] | None = None,
+ updated_at__range: datetime | None = None,
+ updated_at__year: int | None = None,
+ updated_at__month: int | None = None,
+ updated_at__day: int | None = None,
+ updated_at__in: list[datetime] | None = None,
+ updated_at__isnull: bool | None = None,
+ ) -> "CourseGroupQuery":
+ """Filter by Q-expressions or field lookups."""
+ ...
+
+ def exclude(
+ self,
+ *args: Any,
+ course: Course | None = None,
+ course__in: list[Course] | None = None,
+ course__isnull: bool | None = None,
+ course_id: int | None = None,
+ course_id__gt: int | None = None,
+ course_id__gte: int | None = None,
+ course_id__lt: int | None = None,
+ course_id__lte: int | None = None,
+ course_id__between: tuple[int, int] | None = None,
+ course_id__range: int | None = None,
+ course_id__in: list[int] | None = None,
+ course_id__isnull: bool | None = None,
+ created_at: datetime | None = None,
+ created_at__gt: datetime | None = None,
+ created_at__gte: datetime | None = None,
+ created_at__lt: datetime | None = None,
+ created_at__lte: datetime | None = None,
+ created_at__between: tuple[datetime, datetime] | None = None,
+ created_at__range: datetime | None = None,
+ created_at__year: int | None = None,
+ created_at__month: int | None = None,
+ created_at__day: int | None = None,
+ created_at__in: list[datetime] | None = None,
+ created_at__isnull: bool | None = None,
+ description: str | None = None,
+ description__contains: str | None = None,
+ description__icontains: str | None = None,
+ description__startswith: str | None = None,
+ description__istartswith: str | None = None,
+ description__endswith: str | None = None,
+ description__iendswith: str | None = None,
+ description__iexact: str | None = None,
+ description__in: list[str] | None = None,
+ description__isnull: bool | None = None,
+ id: int | None = None,
+ id__gt: int | None = None,
+ id__gte: int | None = None,
+ id__lt: int | None = None,
+ id__lte: int | None = None,
+ id__between: tuple[int, int] | None = None,
+ id__range: int | None = None,
+ id__in: list[int] | None = None,
+ id__isnull: bool | None = None,
+ name: str | None = None,
+ name__contains: str | None = None,
+ name__icontains: str | None = None,
+ name__startswith: str | None = None,
+ name__istartswith: str | None = None,
+ name__endswith: str | None = None,
+ name__iendswith: str | None = None,
+ name__iexact: str | None = None,
+ name__in: list[str] | None = None,
+ name__isnull: bool | None = None,
+ updated_at: datetime | None = None,
+ updated_at__gt: datetime | None = None,
+ updated_at__gte: datetime | None = None,
+ updated_at__lt: datetime | None = None,
+ updated_at__lte: datetime | None = None,
+ updated_at__between: tuple[datetime, datetime] | None = None,
+ updated_at__range: datetime | None = None,
+ updated_at__year: int | None = None,
+ updated_at__month: int | None = None,
+ updated_at__day: int | None = None,
+ updated_at__in: list[datetime] | None = None,
+ updated_at__isnull: bool | None = None,
+ ) -> "CourseGroupQuery":
+ """Exclude objects matching field lookups."""
+ ...
+
+ def order_by(self, *fields: Literal["course", "-course", "course_id", "-course_id", "created_at", "-created_at", "description", "-description", "id", "-id", "name", "-name", "updated_at", "-updated_at"]) -> "CourseGroupQuery": # type: ignore[override]
+ """Order results by fields."""
+ ...
+
+ def limit(self, n: int) -> "CourseGroupQuery":
+ """Limit number of results."""
+ ...
+
+ def offset(self, n: int) -> "CourseGroupQuery":
+ """Skip first n results."""
+ ...
+
+ def distinct(self, value: bool = True) -> "CourseGroupQuery":
+ """Return distinct results."""
+ ...
+
+ def select(self, *fields: Literal["course", "course_id", "created_at", "description", "id", "name", "updated_at"]) -> "CourseGroupQuery": # type: ignore[override]
+ """Select specific fields."""
+ ...
+
+ def join(self, *paths: str) -> "CourseGroupQuery":
+ """Perform LEFT JOIN for relations."""
+ ...
+
+ def prefetch(self, *paths: str) -> "CourseGroupQuery":
+ """Prefetch related objects (separate queries)."""
+ ...
+
+ def for_update(self) -> "CourseGroupQuery":
+ """Add FOR UPDATE lock to query."""
+ ...
+
+ def for_share(self) -> "CourseGroupQuery":
+ """Add FOR SHARE lock to query."""
+ ...
+
+ def annotate(self, **annotations: Any) -> "CourseGroupQuery":
+ """Add computed fields using aggregate functions."""
+ ...
+
+ def group_by(self, *fields: Literal["course", "course_id", "created_at", "description", "id", "name", "updated_at"]) -> "CourseGroupQuery": # type: ignore[override]
+ """Add GROUP BY clause."""
+ ...
+
+ def having(self, *q_exprs: Any, **kwargs: Any) -> "CourseGroupQuery":
+ """Add HAVING clause for filtering grouped results."""
+ ...
+
+ def values(self, *fields: Literal["course", "course_id", "created_at", "description", "id", "name", "updated_at"]) -> "CourseGroupQuery": # type: ignore[override]
+ """Return dicts instead of models."""
+ ...
+
+ def values_list(self, *fields: Literal["course", "course_id", "created_at", "description", "id", "name", "updated_at"], flat: bool = False) -> "CourseGroupQuery": # type: ignore[override]
+ """Return tuples/values instead of models."""
+ ...
+
+ # Terminal methods (async, execute query)
+
+ async def all(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> list[CourseGroup]:
+ """Execute query and return all results."""
+ ...
+
+ async def first(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> CourseGroup | None:
+ """Execute query and return first result."""
+ ...
+
+ async def last(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> CourseGroup | None:
+ """Execute query and return last result."""
+ ...
+
+ async def count(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> int:
+ """Count matching objects."""
+ ...
+
+ async def sum(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Calculate sum of field values."""
+ ...
+
+ async def avg(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Calculate average of field values."""
+ ...
+
+ async def max(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Get maximum field value."""
+ ...
+
+ async def min(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Get minimum field value."""
+ ...
+
+ async def update( # type: ignore[override]
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ **values: Any,
+ ) -> int:
+ """Update matching objects."""
+ ...
+
+ async def increment(
+ self,
+ field: str,
+ by: int | float = 1,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> int:
+ """Atomically increment a field value."""
+ ...
+
+ async def delete(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> int:
+ """Delete matching objects."""
+ ...
+
+class CourseGroupManager(QueryManager[CourseGroup]):
+ """Type-safe Manager for CourseGroup model."""
+
+ # Query building methods (sync, return Query)
+
+ def query(self) -> CourseGroupQuery:
+ """Return a Query builder for this model."""
+ ...
+
+ def filter(
+ self,
+ *args: Any,
+ course: Course | None = None,
+ course__in: list[Course] | None = None,
+ course__isnull: bool | None = None,
+ course_id: int | None = None,
+ course_id__gt: int | None = None,
+ course_id__gte: int | None = None,
+ course_id__lt: int | None = None,
+ course_id__lte: int | None = None,
+ course_id__between: tuple[int, int] | None = None,
+ course_id__range: int | None = None,
+ course_id__in: list[int] | None = None,
+ course_id__isnull: bool | None = None,
+ created_at: datetime | None = None,
+ created_at__gt: datetime | None = None,
+ created_at__gte: datetime | None = None,
+ created_at__lt: datetime | None = None,
+ created_at__lte: datetime | None = None,
+ created_at__between: tuple[datetime, datetime] | None = None,
+ created_at__range: datetime | None = None,
+ created_at__year: int | None = None,
+ created_at__month: int | None = None,
+ created_at__day: int | None = None,
+ created_at__in: list[datetime] | None = None,
+ created_at__isnull: bool | None = None,
+ description: str | None = None,
+ description__contains: str | None = None,
+ description__icontains: str | None = None,
+ description__startswith: str | None = None,
+ description__istartswith: str | None = None,
+ description__endswith: str | None = None,
+ description__iendswith: str | None = None,
+ description__iexact: str | None = None,
+ description__in: list[str] | None = None,
+ description__isnull: bool | None = None,
+ id: int | None = None,
+ id__gt: int | None = None,
+ id__gte: int | None = None,
+ id__lt: int | None = None,
+ id__lte: int | None = None,
+ id__between: tuple[int, int] | None = None,
+ id__range: int | None = None,
+ id__in: list[int] | None = None,
+ id__isnull: bool | None = None,
+ name: str | None = None,
+ name__contains: str | None = None,
+ name__icontains: str | None = None,
+ name__startswith: str | None = None,
+ name__istartswith: str | None = None,
+ name__endswith: str | None = None,
+ name__iendswith: str | None = None,
+ name__iexact: str | None = None,
+ name__in: list[str] | None = None,
+ name__isnull: bool | None = None,
+ updated_at: datetime | None = None,
+ updated_at__gt: datetime | None = None,
+ updated_at__gte: datetime | None = None,
+ updated_at__lt: datetime | None = None,
+ updated_at__lte: datetime | None = None,
+ updated_at__between: tuple[datetime, datetime] | None = None,
+ updated_at__range: datetime | None = None,
+ updated_at__year: int | None = None,
+ updated_at__month: int | None = None,
+ updated_at__day: int | None = None,
+ updated_at__in: list[datetime] | None = None,
+ updated_at__isnull: bool | None = None,
+ ) -> CourseGroupQuery:
+ """Filter by Q-expressions or field lookups."""
+ ...
+
+ def exclude(
+ self,
+ *args: Any,
+ course: Course | None = None,
+ course__in: list[Course] | None = None,
+ course__isnull: bool | None = None,
+ course_id: int | None = None,
+ course_id__gt: int | None = None,
+ course_id__gte: int | None = None,
+ course_id__lt: int | None = None,
+ course_id__lte: int | None = None,
+ course_id__between: tuple[int, int] | None = None,
+ course_id__range: int | None = None,
+ course_id__in: list[int] | None = None,
+ course_id__isnull: bool | None = None,
+ created_at: datetime | None = None,
+ created_at__gt: datetime | None = None,
+ created_at__gte: datetime | None = None,
+ created_at__lt: datetime | None = None,
+ created_at__lte: datetime | None = None,
+ created_at__between: tuple[datetime, datetime] | None = None,
+ created_at__range: datetime | None = None,
+ created_at__year: int | None = None,
+ created_at__month: int | None = None,
+ created_at__day: int | None = None,
+ created_at__in: list[datetime] | None = None,
+ created_at__isnull: bool | None = None,
+ description: str | None = None,
+ description__contains: str | None = None,
+ description__icontains: str | None = None,
+ description__startswith: str | None = None,
+ description__istartswith: str | None = None,
+ description__endswith: str | None = None,
+ description__iendswith: str | None = None,
+ description__iexact: str | None = None,
+ description__in: list[str] | None = None,
+ description__isnull: bool | None = None,
+ id: int | None = None,
+ id__gt: int | None = None,
+ id__gte: int | None = None,
+ id__lt: int | None = None,
+ id__lte: int | None = None,
+ id__between: tuple[int, int] | None = None,
+ id__range: int | None = None,
+ id__in: list[int] | None = None,
+ id__isnull: bool | None = None,
+ name: str | None = None,
+ name__contains: str | None = None,
+ name__icontains: str | None = None,
+ name__startswith: str | None = None,
+ name__istartswith: str | None = None,
+ name__endswith: str | None = None,
+ name__iendswith: str | None = None,
+ name__iexact: str | None = None,
+ name__in: list[str] | None = None,
+ name__isnull: bool | None = None,
+ updated_at: datetime | None = None,
+ updated_at__gt: datetime | None = None,
+ updated_at__gte: datetime | None = None,
+ updated_at__lt: datetime | None = None,
+ updated_at__lte: datetime | None = None,
+ updated_at__between: tuple[datetime, datetime] | None = None,
+ updated_at__range: datetime | None = None,
+ updated_at__year: int | None = None,
+ updated_at__month: int | None = None,
+ updated_at__day: int | None = None,
+ updated_at__in: list[datetime] | None = None,
+ updated_at__isnull: bool | None = None,
+ ) -> CourseGroupQuery:
+ """Exclude objects matching field lookups."""
+ ...
+
+ def values(self, *fields: Literal["course", "course_id", "created_at", "description", "id", "name", "updated_at"]) -> CourseGroupQuery: # type: ignore[override]
+ """Return dicts instead of models."""
+ ...
+
+ def values_list(self, *fields: Literal["course", "course_id", "created_at", "description", "id", "name", "updated_at"], flat: bool = False) -> CourseGroupQuery: # type: ignore[override]
+ """Return tuples/values instead of models."""
+ ...
+
+ def distinct(self, distinct: bool = True) -> CourseGroupQuery:
+ """Return distinct results."""
+ ...
+
+ def join(self, *paths: str) -> CourseGroupQuery:
+ """Perform LEFT JOIN for relations."""
+ ...
+
+ def prefetch(self, *paths: str) -> CourseGroupQuery:
+ """Prefetch related objects (separate queries)."""
+ ...
+
+ def for_update(self) -> CourseGroupQuery:
+ """Add FOR UPDATE lock to query."""
+ ...
+
+ def for_share(self) -> CourseGroupQuery:
+ """Add FOR SHARE lock to query."""
+ ...
+
+ # Terminal methods (async, execute query)
+
+ async def get(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ **filters: Any,
+ ) -> CourseGroup:
+ """Get single object matching lookups."""
+ ...
+
+ async def get_or_none(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ **filters: Any,
+ ) -> CourseGroup | None:
+ """Get object or None if not found."""
+ ...
+
+ async def get_or_create(
+ self,
+ *,
+ defaults: dict[str, Any] | None = None,
+ client: Any | None = None,
+ using: str | None = None,
+ **filters: Any,
+ ) -> tuple[CourseGroup, bool]:
+ """Get object or create if not found. Returns (object, created)."""
+ ...
+
+ async def update_or_create(
+ self,
+ *,
+ defaults: dict[str, Any] | None = None,
+ client: Any | None = None,
+ using: str | None = None,
+ **filters: Any,
+ ) -> tuple[CourseGroup, bool]:
+ """Get object, create if missing, or update it when defaults are provided."""
+ ...
+
+ async def all(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ mode: str = "models",
+ ) -> list[CourseGroup]:
+ """Get all objects."""
+ ...
+
+ async def first(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> CourseGroup | None:
+ """Get first object."""
+ ...
+
+ async def last(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> CourseGroup | None:
+ """Get last object."""
+ ...
+
+ async def count(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> int:
+ """Count all objects."""
+ ...
+
+ async def sum(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Calculate sum of field values."""
+ ...
+
+ async def avg(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Calculate average of field values."""
+ ...
+
+ async def max(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Get maximum field value."""
+ ...
+
+ async def min(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Get minimum field value."""
+ ...
+
+ async def create( # type: ignore[override]
+ self,
+ *,
+ instance: CourseGroup | None = None,
+ client: Any | None = None,
+ using: str | None = None,
+ course: Course | None = None,
+ course_id: int | None = None,
+ created_at: datetime | None = None,
+ description: str | None = None,
+ id: int | None = None,
+ name: str | None = None,
+ updated_at: datetime | None = None,
+ ) -> CourseGroup:
+ """Create new object."""
+ ...
+
+ async def bulk_create( # type: ignore[override]
+ self,
+ objects: list[CourseGroup],
+ *,
+ batch_size: int | None = None,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> list[CourseGroup]:
+ """Bulk create objects."""
+ ...
+
+ async def bulk_update( # type: ignore[override]
+ self,
+ objects: list[CourseGroup],
+ fields: list[str],
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> int:
+ """Bulk update objects."""
+ ...
+
+
+class CourseGroupPermission(Model):
+ class Meta:
+ is_table: bool
+ table_name: str
+ id: int | None
+ group: CourseGroup | None
+ permission: str
+ group_id: int | None
+ objects: ClassVar["CourseGroupPermissionManager"]
+
+
+class CourseGroupPermissionQuery(Query[CourseGroupPermission]):
+ """Type-safe Query for CourseGroupPermission model."""
+
+ # Query building methods (sync, return Query)
+
+ def filter(
+ self,
+ *args: Any,
+ group: CourseGroup | None = None,
+ group__in: list[CourseGroup] | None = None,
+ group__isnull: bool | None = None,
+ group_id: int | None = None,
+ group_id__gt: int | None = None,
+ group_id__gte: int | None = None,
+ group_id__lt: int | None = None,
+ group_id__lte: int | None = None,
+ group_id__between: tuple[int, int] | None = None,
+ group_id__range: int | None = None,
+ group_id__in: list[int] | None = None,
+ group_id__isnull: bool | None = None,
+ id: int | None = None,
+ id__gt: int | None = None,
+ id__gte: int | None = None,
+ id__lt: int | None = None,
+ id__lte: int | None = None,
+ id__between: tuple[int, int] | None = None,
+ id__range: int | None = None,
+ id__in: list[int] | None = None,
+ id__isnull: bool | None = None,
+ permission: str | None = None,
+ permission__contains: str | None = None,
+ permission__icontains: str | None = None,
+ permission__startswith: str | None = None,
+ permission__istartswith: str | None = None,
+ permission__endswith: str | None = None,
+ permission__iendswith: str | None = None,
+ permission__iexact: str | None = None,
+ permission__in: list[str] | None = None,
+ permission__isnull: bool | None = None,
+ ) -> "CourseGroupPermissionQuery":
+ """Filter by Q-expressions or field lookups."""
+ ...
+
+ def exclude(
+ self,
+ *args: Any,
+ group: CourseGroup | None = None,
+ group__in: list[CourseGroup] | None = None,
+ group__isnull: bool | None = None,
+ group_id: int | None = None,
+ group_id__gt: int | None = None,
+ group_id__gte: int | None = None,
+ group_id__lt: int | None = None,
+ group_id__lte: int | None = None,
+ group_id__between: tuple[int, int] | None = None,
+ group_id__range: int | None = None,
+ group_id__in: list[int] | None = None,
+ group_id__isnull: bool | None = None,
+ id: int | None = None,
+ id__gt: int | None = None,
+ id__gte: int | None = None,
+ id__lt: int | None = None,
+ id__lte: int | None = None,
+ id__between: tuple[int, int] | None = None,
+ id__range: int | None = None,
+ id__in: list[int] | None = None,
+ id__isnull: bool | None = None,
+ permission: str | None = None,
+ permission__contains: str | None = None,
+ permission__icontains: str | None = None,
+ permission__startswith: str | None = None,
+ permission__istartswith: str | None = None,
+ permission__endswith: str | None = None,
+ permission__iendswith: str | None = None,
+ permission__iexact: str | None = None,
+ permission__in: list[str] | None = None,
+ permission__isnull: bool | None = None,
+ ) -> "CourseGroupPermissionQuery":
+ """Exclude objects matching field lookups."""
+ ...
+
+ def order_by(self, *fields: Literal["group", "-group", "group_id", "-group_id", "id", "-id", "permission", "-permission"]) -> "CourseGroupPermissionQuery": # type: ignore[override]
+ """Order results by fields."""
+ ...
+
+ def limit(self, n: int) -> "CourseGroupPermissionQuery":
+ """Limit number of results."""
+ ...
+
+ def offset(self, n: int) -> "CourseGroupPermissionQuery":
+ """Skip first n results."""
+ ...
+
+ def distinct(self, value: bool = True) -> "CourseGroupPermissionQuery":
+ """Return distinct results."""
+ ...
+
+ def select(self, *fields: Literal["group", "group_id", "id", "permission"]) -> "CourseGroupPermissionQuery": # type: ignore[override]
+ """Select specific fields."""
+ ...
+
+ def join(self, *paths: str) -> "CourseGroupPermissionQuery":
+ """Perform LEFT JOIN for relations."""
+ ...
+
+ def prefetch(self, *paths: str) -> "CourseGroupPermissionQuery":
+ """Prefetch related objects (separate queries)."""
+ ...
+
+ def for_update(self) -> "CourseGroupPermissionQuery":
+ """Add FOR UPDATE lock to query."""
+ ...
+
+ def for_share(self) -> "CourseGroupPermissionQuery":
+ """Add FOR SHARE lock to query."""
+ ...
+
+ def annotate(self, **annotations: Any) -> "CourseGroupPermissionQuery":
+ """Add computed fields using aggregate functions."""
+ ...
+
+ def group_by(self, *fields: Literal["group", "group_id", "id", "permission"]) -> "CourseGroupPermissionQuery": # type: ignore[override]
+ """Add GROUP BY clause."""
+ ...
+
+ def having(self, *q_exprs: Any, **kwargs: Any) -> "CourseGroupPermissionQuery":
+ """Add HAVING clause for filtering grouped results."""
+ ...
+
+ def values(self, *fields: Literal["group", "group_id", "id", "permission"]) -> "CourseGroupPermissionQuery": # type: ignore[override]
+ """Return dicts instead of models."""
+ ...
+
+ def values_list(self, *fields: Literal["group", "group_id", "id", "permission"], flat: bool = False) -> "CourseGroupPermissionQuery": # type: ignore[override]
+ """Return tuples/values instead of models."""
+ ...
+
+ # Terminal methods (async, execute query)
+
+ async def all(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> list[CourseGroupPermission]:
+ """Execute query and return all results."""
+ ...
+
+ async def first(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> CourseGroupPermission | None:
+ """Execute query and return first result."""
+ ...
+
+ async def last(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> CourseGroupPermission | None:
+ """Execute query and return last result."""
+ ...
+
+ async def count(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> int:
+ """Count matching objects."""
+ ...
+
+ async def sum(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Calculate sum of field values."""
+ ...
+
+ async def avg(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Calculate average of field values."""
+ ...
+
+ async def max(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Get maximum field value."""
+ ...
+
+ async def min(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Get minimum field value."""
+ ...
+
+ async def update( # type: ignore[override]
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ **values: Any,
+ ) -> int:
+ """Update matching objects."""
+ ...
+
+ async def increment(
+ self,
+ field: str,
+ by: int | float = 1,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> int:
+ """Atomically increment a field value."""
+ ...
+
+ async def delete(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> int:
+ """Delete matching objects."""
+ ...
+
+class CourseGroupPermissionManager(QueryManager[CourseGroupPermission]):
+ """Type-safe Manager for CourseGroupPermission model."""
+
+ # Query building methods (sync, return Query)
+
+ def query(self) -> CourseGroupPermissionQuery:
+ """Return a Query builder for this model."""
+ ...
+
+ def filter(
+ self,
+ *args: Any,
+ group: CourseGroup | None = None,
+ group__in: list[CourseGroup] | None = None,
+ group__isnull: bool | None = None,
+ group_id: int | None = None,
+ group_id__gt: int | None = None,
+ group_id__gte: int | None = None,
+ group_id__lt: int | None = None,
+ group_id__lte: int | None = None,
+ group_id__between: tuple[int, int] | None = None,
+ group_id__range: int | None = None,
+ group_id__in: list[int] | None = None,
+ group_id__isnull: bool | None = None,
+ id: int | None = None,
+ id__gt: int | None = None,
+ id__gte: int | None = None,
+ id__lt: int | None = None,
+ id__lte: int | None = None,
+ id__between: tuple[int, int] | None = None,
+ id__range: int | None = None,
+ id__in: list[int] | None = None,
+ id__isnull: bool | None = None,
+ permission: str | None = None,
+ permission__contains: str | None = None,
+ permission__icontains: str | None = None,
+ permission__startswith: str | None = None,
+ permission__istartswith: str | None = None,
+ permission__endswith: str | None = None,
+ permission__iendswith: str | None = None,
+ permission__iexact: str | None = None,
+ permission__in: list[str] | None = None,
+ permission__isnull: bool | None = None,
+ ) -> CourseGroupPermissionQuery:
+ """Filter by Q-expressions or field lookups."""
+ ...
+
+ def exclude(
+ self,
+ *args: Any,
+ group: CourseGroup | None = None,
+ group__in: list[CourseGroup] | None = None,
+ group__isnull: bool | None = None,
+ group_id: int | None = None,
+ group_id__gt: int | None = None,
+ group_id__gte: int | None = None,
+ group_id__lt: int | None = None,
+ group_id__lte: int | None = None,
+ group_id__between: tuple[int, int] | None = None,
+ group_id__range: int | None = None,
+ group_id__in: list[int] | None = None,
+ group_id__isnull: bool | None = None,
+ id: int | None = None,
+ id__gt: int | None = None,
+ id__gte: int | None = None,
+ id__lt: int | None = None,
+ id__lte: int | None = None,
+ id__between: tuple[int, int] | None = None,
+ id__range: int | None = None,
+ id__in: list[int] | None = None,
+ id__isnull: bool | None = None,
+ permission: str | None = None,
+ permission__contains: str | None = None,
+ permission__icontains: str | None = None,
+ permission__startswith: str | None = None,
+ permission__istartswith: str | None = None,
+ permission__endswith: str | None = None,
+ permission__iendswith: str | None = None,
+ permission__iexact: str | None = None,
+ permission__in: list[str] | None = None,
+ permission__isnull: bool | None = None,
+ ) -> CourseGroupPermissionQuery:
+ """Exclude objects matching field lookups."""
+ ...
+
+ def values(self, *fields: Literal["group", "group_id", "id", "permission"]) -> CourseGroupPermissionQuery: # type: ignore[override]
+ """Return dicts instead of models."""
+ ...
+
+ def values_list(self, *fields: Literal["group", "group_id", "id", "permission"], flat: bool = False) -> CourseGroupPermissionQuery: # type: ignore[override]
+ """Return tuples/values instead of models."""
+ ...
+
+ def distinct(self, distinct: bool = True) -> CourseGroupPermissionQuery:
+ """Return distinct results."""
+ ...
+
+ def join(self, *paths: str) -> CourseGroupPermissionQuery:
+ """Perform LEFT JOIN for relations."""
+ ...
+
+ def prefetch(self, *paths: str) -> CourseGroupPermissionQuery:
+ """Prefetch related objects (separate queries)."""
+ ...
+
+ def for_update(self) -> CourseGroupPermissionQuery:
+ """Add FOR UPDATE lock to query."""
+ ...
+
+ def for_share(self) -> CourseGroupPermissionQuery:
+ """Add FOR SHARE lock to query."""
+ ...
+
+ # Terminal methods (async, execute query)
+
+ async def get(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ **filters: Any,
+ ) -> CourseGroupPermission:
+ """Get single object matching lookups."""
+ ...
+
+ async def get_or_none(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ **filters: Any,
+ ) -> CourseGroupPermission | None:
+ """Get object or None if not found."""
+ ...
+
+ async def get_or_create(
+ self,
+ *,
+ defaults: dict[str, Any] | None = None,
+ client: Any | None = None,
+ using: str | None = None,
+ **filters: Any,
+ ) -> tuple[CourseGroupPermission, bool]:
+ """Get object or create if not found. Returns (object, created)."""
+ ...
+
+ async def update_or_create(
+ self,
+ *,
+ defaults: dict[str, Any] | None = None,
+ client: Any | None = None,
+ using: str | None = None,
+ **filters: Any,
+ ) -> tuple[CourseGroupPermission, bool]:
+ """Get object, create if missing, or update it when defaults are provided."""
+ ...
+
+ async def all(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ mode: str = "models",
+ ) -> list[CourseGroupPermission]:
+ """Get all objects."""
+ ...
+
+ async def first(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> CourseGroupPermission | None:
+ """Get first object."""
+ ...
+
+ async def last(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> CourseGroupPermission | None:
+ """Get last object."""
+ ...
+
+ async def count(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> int:
+ """Count all objects."""
+ ...
+
+ async def sum(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Calculate sum of field values."""
+ ...
+
+ async def avg(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Calculate average of field values."""
+ ...
+
+ async def max(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Get maximum field value."""
+ ...
+
+ async def min(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Get minimum field value."""
+ ...
+
+ async def create( # type: ignore[override]
+ self,
+ *,
+ instance: CourseGroupPermission | None = None,
+ client: Any | None = None,
+ using: str | None = None,
+ group: CourseGroup | None = None,
+ group_id: int | None = None,
+ id: int | None = None,
+ permission: str | None = None,
+ ) -> CourseGroupPermission:
+ """Create new object."""
+ ...
+
+ async def bulk_create( # type: ignore[override]
+ self,
+ objects: list[CourseGroupPermission],
+ *,
+ batch_size: int | None = None,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> list[CourseGroupPermission]:
+ """Bulk create objects."""
+ ...
+
+ async def bulk_update( # type: ignore[override]
+ self,
+ objects: list[CourseGroupPermission],
+ fields: list[str],
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> int:
+ """Bulk update objects."""
+ ...
+
+
+class CourseMember(Model):
+ class Meta:
+ is_table: bool
+ table_name: str
+ id: int | None
+ group: CourseGroup | None
+ user: User | None
+ created_at: datetime | None
+ group_id: int | None
+ user_id: int | None
+ objects: ClassVar["CourseMemberManager"]
+
+
+class CourseMemberQuery(Query[CourseMember]):
+ """Type-safe Query for CourseMember model."""
+
+ # Query building methods (sync, return Query)
+
+ def filter(
+ self,
+ *args: Any,
+ created_at: datetime | None = None,
+ created_at__gt: datetime | None = None,
+ created_at__gte: datetime | None = None,
+ created_at__lt: datetime | None = None,
+ created_at__lte: datetime | None = None,
+ created_at__between: tuple[datetime, datetime] | None = None,
+ created_at__range: datetime | None = None,
+ created_at__year: int | None = None,
+ created_at__month: int | None = None,
+ created_at__day: int | None = None,
+ created_at__in: list[datetime] | None = None,
+ created_at__isnull: bool | None = None,
+ group: CourseGroup | None = None,
+ group__in: list[CourseGroup] | None = None,
+ group__isnull: bool | None = None,
+ group_id: int | None = None,
+ group_id__gt: int | None = None,
+ group_id__gte: int | None = None,
+ group_id__lt: int | None = None,
+ group_id__lte: int | None = None,
+ group_id__between: tuple[int, int] | None = None,
+ group_id__range: int | None = None,
+ group_id__in: list[int] | None = None,
+ group_id__isnull: bool | None = None,
+ id: int | None = None,
+ id__gt: int | None = None,
+ id__gte: int | None = None,
+ id__lt: int | None = None,
+ id__lte: int | None = None,
+ id__between: tuple[int, int] | None = None,
+ id__range: int | None = None,
+ id__in: list[int] | None = None,
+ id__isnull: bool | None = None,
+ user: User | None = None,
+ user__in: list[User] | None = None,
+ user__isnull: bool | None = None,
+ user_id: int | None = None,
+ user_id__gt: int | None = None,
+ user_id__gte: int | None = None,
+ user_id__lt: int | None = None,
+ user_id__lte: int | None = None,
+ user_id__between: tuple[int, int] | None = None,
+ user_id__range: int | None = None,
+ user_id__in: list[int] | None = None,
+ user_id__isnull: bool | None = None,
+ ) -> "CourseMemberQuery":
+ """Filter by Q-expressions or field lookups."""
+ ...
+
+ def exclude(
+ self,
+ *args: Any,
+ created_at: datetime | None = None,
+ created_at__gt: datetime | None = None,
+ created_at__gte: datetime | None = None,
+ created_at__lt: datetime | None = None,
+ created_at__lte: datetime | None = None,
+ created_at__between: tuple[datetime, datetime] | None = None,
+ created_at__range: datetime | None = None,
+ created_at__year: int | None = None,
+ created_at__month: int | None = None,
+ created_at__day: int | None = None,
+ created_at__in: list[datetime] | None = None,
+ created_at__isnull: bool | None = None,
+ group: CourseGroup | None = None,
+ group__in: list[CourseGroup] | None = None,
+ group__isnull: bool | None = None,
+ group_id: int | None = None,
+ group_id__gt: int | None = None,
+ group_id__gte: int | None = None,
+ group_id__lt: int | None = None,
+ group_id__lte: int | None = None,
+ group_id__between: tuple[int, int] | None = None,
+ group_id__range: int | None = None,
+ group_id__in: list[int] | None = None,
+ group_id__isnull: bool | None = None,
+ id: int | None = None,
+ id__gt: int | None = None,
+ id__gte: int | None = None,
+ id__lt: int | None = None,
+ id__lte: int | None = None,
+ id__between: tuple[int, int] | None = None,
+ id__range: int | None = None,
+ id__in: list[int] | None = None,
+ id__isnull: bool | None = None,
+ user: User | None = None,
+ user__in: list[User] | None = None,
+ user__isnull: bool | None = None,
+ user_id: int | None = None,
+ user_id__gt: int | None = None,
+ user_id__gte: int | None = None,
+ user_id__lt: int | None = None,
+ user_id__lte: int | None = None,
+ user_id__between: tuple[int, int] | None = None,
+ user_id__range: int | None = None,
+ user_id__in: list[int] | None = None,
+ user_id__isnull: bool | None = None,
+ ) -> "CourseMemberQuery":
+ """Exclude objects matching field lookups."""
+ ...
+
+ def order_by(self, *fields: Literal["created_at", "-created_at", "group", "-group", "group_id", "-group_id", "id", "-id", "user", "-user", "user_id", "-user_id"]) -> "CourseMemberQuery": # type: ignore[override]
+ """Order results by fields."""
+ ...
+
+ def limit(self, n: int) -> "CourseMemberQuery":
+ """Limit number of results."""
+ ...
+
+ def offset(self, n: int) -> "CourseMemberQuery":
+ """Skip first n results."""
+ ...
+
+ def distinct(self, value: bool = True) -> "CourseMemberQuery":
+ """Return distinct results."""
+ ...
+
+ def select(self, *fields: Literal["created_at", "group", "group_id", "id", "user", "user_id"]) -> "CourseMemberQuery": # type: ignore[override]
+ """Select specific fields."""
+ ...
+
+ def join(self, *paths: str) -> "CourseMemberQuery":
+ """Perform LEFT JOIN for relations."""
+ ...
+
+ def prefetch(self, *paths: str) -> "CourseMemberQuery":
+ """Prefetch related objects (separate queries)."""
+ ...
+
+ def for_update(self) -> "CourseMemberQuery":
+ """Add FOR UPDATE lock to query."""
+ ...
+
+ def for_share(self) -> "CourseMemberQuery":
+ """Add FOR SHARE lock to query."""
+ ...
+
+ def annotate(self, **annotations: Any) -> "CourseMemberQuery":
+ """Add computed fields using aggregate functions."""
+ ...
+
+ def group_by(self, *fields: Literal["created_at", "group", "group_id", "id", "user", "user_id"]) -> "CourseMemberQuery": # type: ignore[override]
+ """Add GROUP BY clause."""
+ ...
+
+ def having(self, *q_exprs: Any, **kwargs: Any) -> "CourseMemberQuery":
+ """Add HAVING clause for filtering grouped results."""
+ ...
+
+ def values(self, *fields: Literal["created_at", "group", "group_id", "id", "user", "user_id"]) -> "CourseMemberQuery": # type: ignore[override]
+ """Return dicts instead of models."""
+ ...
+
+ def values_list(self, *fields: Literal["created_at", "group", "group_id", "id", "user", "user_id"], flat: bool = False) -> "CourseMemberQuery": # type: ignore[override]
+ """Return tuples/values instead of models."""
+ ...
+
+ # Terminal methods (async, execute query)
+
+ async def all(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> list[CourseMember]:
+ """Execute query and return all results."""
+ ...
+
+ async def first(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> CourseMember | None:
+ """Execute query and return first result."""
+ ...
+
+ async def last(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> CourseMember | None:
+ """Execute query and return last result."""
+ ...
+
+ async def count(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> int:
+ """Count matching objects."""
+ ...
+
+ async def sum(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Calculate sum of field values."""
+ ...
+
+ async def avg(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Calculate average of field values."""
+ ...
+
+ async def max(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Get maximum field value."""
+ ...
+
+ async def min(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Get minimum field value."""
+ ...
+
+ async def update( # type: ignore[override]
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ **values: Any,
+ ) -> int:
+ """Update matching objects."""
+ ...
+
+ async def increment(
+ self,
+ field: str,
+ by: int | float = 1,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> int:
+ """Atomically increment a field value."""
+ ...
+
+ async def delete(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> int:
+ """Delete matching objects."""
+ ...
+
+class CourseMemberManager(QueryManager[CourseMember]):
+ """Type-safe Manager for CourseMember model."""
+
+ # Query building methods (sync, return Query)
+
+ def query(self) -> CourseMemberQuery:
+ """Return a Query builder for this model."""
+ ...
+
+ def filter(
+ self,
+ *args: Any,
+ created_at: datetime | None = None,
+ created_at__gt: datetime | None = None,
+ created_at__gte: datetime | None = None,
+ created_at__lt: datetime | None = None,
+ created_at__lte: datetime | None = None,
+ created_at__between: tuple[datetime, datetime] | None = None,
+ created_at__range: datetime | None = None,
+ created_at__year: int | None = None,
+ created_at__month: int | None = None,
+ created_at__day: int | None = None,
+ created_at__in: list[datetime] | None = None,
+ created_at__isnull: bool | None = None,
+ group: CourseGroup | None = None,
+ group__in: list[CourseGroup] | None = None,
+ group__isnull: bool | None = None,
+ group_id: int | None = None,
+ group_id__gt: int | None = None,
+ group_id__gte: int | None = None,
+ group_id__lt: int | None = None,
+ group_id__lte: int | None = None,
+ group_id__between: tuple[int, int] | None = None,
+ group_id__range: int | None = None,
+ group_id__in: list[int] | None = None,
+ group_id__isnull: bool | None = None,
+ id: int | None = None,
+ id__gt: int | None = None,
+ id__gte: int | None = None,
+ id__lt: int | None = None,
+ id__lte: int | None = None,
+ id__between: tuple[int, int] | None = None,
+ id__range: int | None = None,
+ id__in: list[int] | None = None,
+ id__isnull: bool | None = None,
+ user: User | None = None,
+ user__in: list[User] | None = None,
+ user__isnull: bool | None = None,
+ user_id: int | None = None,
+ user_id__gt: int | None = None,
+ user_id__gte: int | None = None,
+ user_id__lt: int | None = None,
+ user_id__lte: int | None = None,
+ user_id__between: tuple[int, int] | None = None,
+ user_id__range: int | None = None,
+ user_id__in: list[int] | None = None,
+ user_id__isnull: bool | None = None,
+ ) -> CourseMemberQuery:
+ """Filter by Q-expressions or field lookups."""
+ ...
+
+ def exclude(
+ self,
+ *args: Any,
+ created_at: datetime | None = None,
+ created_at__gt: datetime | None = None,
+ created_at__gte: datetime | None = None,
+ created_at__lt: datetime | None = None,
+ created_at__lte: datetime | None = None,
+ created_at__between: tuple[datetime, datetime] | None = None,
+ created_at__range: datetime | None = None,
+ created_at__year: int | None = None,
+ created_at__month: int | None = None,
+ created_at__day: int | None = None,
+ created_at__in: list[datetime] | None = None,
+ created_at__isnull: bool | None = None,
+ group: CourseGroup | None = None,
+ group__in: list[CourseGroup] | None = None,
+ group__isnull: bool | None = None,
+ group_id: int | None = None,
+ group_id__gt: int | None = None,
+ group_id__gte: int | None = None,
+ group_id__lt: int | None = None,
+ group_id__lte: int | None = None,
+ group_id__between: tuple[int, int] | None = None,
+ group_id__range: int | None = None,
+ group_id__in: list[int] | None = None,
+ group_id__isnull: bool | None = None,
+ id: int | None = None,
+ id__gt: int | None = None,
+ id__gte: int | None = None,
+ id__lt: int | None = None,
+ id__lte: int | None = None,
+ id__between: tuple[int, int] | None = None,
+ id__range: int | None = None,
+ id__in: list[int] | None = None,
+ id__isnull: bool | None = None,
+ user: User | None = None,
+ user__in: list[User] | None = None,
+ user__isnull: bool | None = None,
+ user_id: int | None = None,
+ user_id__gt: int | None = None,
+ user_id__gte: int | None = None,
+ user_id__lt: int | None = None,
+ user_id__lte: int | None = None,
+ user_id__between: tuple[int, int] | None = None,
+ user_id__range: int | None = None,
+ user_id__in: list[int] | None = None,
+ user_id__isnull: bool | None = None,
+ ) -> CourseMemberQuery:
+ """Exclude objects matching field lookups."""
+ ...
+
+ def values(self, *fields: Literal["created_at", "group", "group_id", "id", "user", "user_id"]) -> CourseMemberQuery: # type: ignore[override]
+ """Return dicts instead of models."""
+ ...
+
+ def values_list(self, *fields: Literal["created_at", "group", "group_id", "id", "user", "user_id"], flat: bool = False) -> CourseMemberQuery: # type: ignore[override]
+ """Return tuples/values instead of models."""
+ ...
+
+ def distinct(self, distinct: bool = True) -> CourseMemberQuery:
+ """Return distinct results."""
+ ...
+
+ def join(self, *paths: str) -> CourseMemberQuery:
+ """Perform LEFT JOIN for relations."""
+ ...
+
+ def prefetch(self, *paths: str) -> CourseMemberQuery:
+ """Prefetch related objects (separate queries)."""
+ ...
+
+ def for_update(self) -> CourseMemberQuery:
+ """Add FOR UPDATE lock to query."""
+ ...
+
+ def for_share(self) -> CourseMemberQuery:
+ """Add FOR SHARE lock to query."""
+ ...
+
+ # Terminal methods (async, execute query)
+
+ async def get(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ **filters: Any,
+ ) -> CourseMember:
+ """Get single object matching lookups."""
+ ...
+
+ async def get_or_none(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ **filters: Any,
+ ) -> CourseMember | None:
+ """Get object or None if not found."""
+ ...
+
+ async def get_or_create(
+ self,
+ *,
+ defaults: dict[str, Any] | None = None,
+ client: Any | None = None,
+ using: str | None = None,
+ **filters: Any,
+ ) -> tuple[CourseMember, bool]:
+ """Get object or create if not found. Returns (object, created)."""
+ ...
+
+ async def update_or_create(
+ self,
+ *,
+ defaults: dict[str, Any] | None = None,
+ client: Any | None = None,
+ using: str | None = None,
+ **filters: Any,
+ ) -> tuple[CourseMember, bool]:
+ """Get object, create if missing, or update it when defaults are provided."""
+ ...
+
+ async def all(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ mode: str = "models",
+ ) -> list[CourseMember]:
+ """Get all objects."""
+ ...
+
+ async def first(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> CourseMember | None:
+ """Get first object."""
+ ...
+
+ async def last(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> CourseMember | None:
+ """Get last object."""
+ ...
+
+ async def count(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> int:
+ """Count all objects."""
+ ...
+
+ async def sum(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Calculate sum of field values."""
+ ...
+
+ async def avg(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Calculate average of field values."""
+ ...
+
+ async def max(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Get maximum field value."""
+ ...
+
+ async def min(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Get minimum field value."""
+ ...
+
+ async def create( # type: ignore[override]
+ self,
+ *,
+ instance: CourseMember | None = None,
+ client: Any | None = None,
+ using: str | None = None,
+ created_at: datetime | None = None,
+ group: CourseGroup | None = None,
+ group_id: int | None = None,
+ id: int | None = None,
+ user: User | None = None,
+ user_id: int | None = None,
+ ) -> CourseMember:
+ """Create new object."""
+ ...
+
+ async def bulk_create( # type: ignore[override]
+ self,
+ objects: list[CourseMember],
+ *,
+ batch_size: int | None = None,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> list[CourseMember]:
+ """Bulk create objects."""
+ ...
+
+ async def bulk_update( # type: ignore[override]
+ self,
+ objects: list[CourseMember],
+ fields: list[str],
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> int:
+ """Bulk update objects."""
+ ...
+
diff --git a/freenit/models/sql/project.pyi b/freenit/models/sql/project.pyi
index cd33f84..621b9f1 100644
--- a/freenit/models/sql/project.pyi
+++ b/freenit/models/sql/project.pyi
@@ -2828,3 +2828,1786 @@ class TaskManager(QueryManager[Task]):
"""Bulk update objects."""
...
+
+class ProjectGroup(Model):
+ class Meta:
+ is_table: bool
+ table_name: str
+ id: int | None
+ project: Project | None
+ name: str
+ description: str | None
+ created_at: datetime | None
+ updated_at: datetime | None
+ project_id: int | None
+ objects: ClassVar["ProjectGroupManager"]
+
+
+class ProjectGroupQuery(Query[ProjectGroup]):
+ """Type-safe Query for ProjectGroup model."""
+
+ # Query building methods (sync, return Query)
+
+ def filter(
+ self,
+ *args: Any,
+ created_at: datetime | None = None,
+ created_at__gt: datetime | None = None,
+ created_at__gte: datetime | None = None,
+ created_at__lt: datetime | None = None,
+ created_at__lte: datetime | None = None,
+ created_at__between: tuple[datetime, datetime] | None = None,
+ created_at__range: datetime | None = None,
+ created_at__year: int | None = None,
+ created_at__month: int | None = None,
+ created_at__day: int | None = None,
+ created_at__in: list[datetime] | None = None,
+ created_at__isnull: bool | None = None,
+ description: str | None = None,
+ description__contains: str | None = None,
+ description__icontains: str | None = None,
+ description__startswith: str | None = None,
+ description__istartswith: str | None = None,
+ description__endswith: str | None = None,
+ description__iendswith: str | None = None,
+ description__iexact: str | None = None,
+ description__in: list[str] | None = None,
+ description__isnull: bool | None = None,
+ id: int | None = None,
+ id__gt: int | None = None,
+ id__gte: int | None = None,
+ id__lt: int | None = None,
+ id__lte: int | None = None,
+ id__between: tuple[int, int] | None = None,
+ id__range: int | None = None,
+ id__in: list[int] | None = None,
+ id__isnull: bool | None = None,
+ name: str | None = None,
+ name__contains: str | None = None,
+ name__icontains: str | None = None,
+ name__startswith: str | None = None,
+ name__istartswith: str | None = None,
+ name__endswith: str | None = None,
+ name__iendswith: str | None = None,
+ name__iexact: str | None = None,
+ name__in: list[str] | None = None,
+ name__isnull: bool | None = None,
+ project: Project | None = None,
+ project__in: list[Project] | None = None,
+ project__isnull: bool | None = None,
+ project_id: int | None = None,
+ project_id__gt: int | None = None,
+ project_id__gte: int | None = None,
+ project_id__lt: int | None = None,
+ project_id__lte: int | None = None,
+ project_id__between: tuple[int, int] | None = None,
+ project_id__range: int | None = None,
+ project_id__in: list[int] | None = None,
+ project_id__isnull: bool | None = None,
+ updated_at: datetime | None = None,
+ updated_at__gt: datetime | None = None,
+ updated_at__gte: datetime | None = None,
+ updated_at__lt: datetime | None = None,
+ updated_at__lte: datetime | None = None,
+ updated_at__between: tuple[datetime, datetime] | None = None,
+ updated_at__range: datetime | None = None,
+ updated_at__year: int | None = None,
+ updated_at__month: int | None = None,
+ updated_at__day: int | None = None,
+ updated_at__in: list[datetime] | None = None,
+ updated_at__isnull: bool | None = None,
+ ) -> "ProjectGroupQuery":
+ """Filter by Q-expressions or field lookups."""
+ ...
+
+ def exclude(
+ self,
+ *args: Any,
+ created_at: datetime | None = None,
+ created_at__gt: datetime | None = None,
+ created_at__gte: datetime | None = None,
+ created_at__lt: datetime | None = None,
+ created_at__lte: datetime | None = None,
+ created_at__between: tuple[datetime, datetime] | None = None,
+ created_at__range: datetime | None = None,
+ created_at__year: int | None = None,
+ created_at__month: int | None = None,
+ created_at__day: int | None = None,
+ created_at__in: list[datetime] | None = None,
+ created_at__isnull: bool | None = None,
+ description: str | None = None,
+ description__contains: str | None = None,
+ description__icontains: str | None = None,
+ description__startswith: str | None = None,
+ description__istartswith: str | None = None,
+ description__endswith: str | None = None,
+ description__iendswith: str | None = None,
+ description__iexact: str | None = None,
+ description__in: list[str] | None = None,
+ description__isnull: bool | None = None,
+ id: int | None = None,
+ id__gt: int | None = None,
+ id__gte: int | None = None,
+ id__lt: int | None = None,
+ id__lte: int | None = None,
+ id__between: tuple[int, int] | None = None,
+ id__range: int | None = None,
+ id__in: list[int] | None = None,
+ id__isnull: bool | None = None,
+ name: str | None = None,
+ name__contains: str | None = None,
+ name__icontains: str | None = None,
+ name__startswith: str | None = None,
+ name__istartswith: str | None = None,
+ name__endswith: str | None = None,
+ name__iendswith: str | None = None,
+ name__iexact: str | None = None,
+ name__in: list[str] | None = None,
+ name__isnull: bool | None = None,
+ project: Project | None = None,
+ project__in: list[Project] | None = None,
+ project__isnull: bool | None = None,
+ project_id: int | None = None,
+ project_id__gt: int | None = None,
+ project_id__gte: int | None = None,
+ project_id__lt: int | None = None,
+ project_id__lte: int | None = None,
+ project_id__between: tuple[int, int] | None = None,
+ project_id__range: int | None = None,
+ project_id__in: list[int] | None = None,
+ project_id__isnull: bool | None = None,
+ updated_at: datetime | None = None,
+ updated_at__gt: datetime | None = None,
+ updated_at__gte: datetime | None = None,
+ updated_at__lt: datetime | None = None,
+ updated_at__lte: datetime | None = None,
+ updated_at__between: tuple[datetime, datetime] | None = None,
+ updated_at__range: datetime | None = None,
+ updated_at__year: int | None = None,
+ updated_at__month: int | None = None,
+ updated_at__day: int | None = None,
+ updated_at__in: list[datetime] | None = None,
+ updated_at__isnull: bool | None = None,
+ ) -> "ProjectGroupQuery":
+ """Exclude objects matching field lookups."""
+ ...
+
+ def order_by(self, *fields: Literal["created_at", "-created_at", "description", "-description", "id", "-id", "name", "-name", "project", "-project", "project_id", "-project_id", "updated_at", "-updated_at"]) -> "ProjectGroupQuery": # type: ignore[override]
+ """Order results by fields."""
+ ...
+
+ def limit(self, n: int) -> "ProjectGroupQuery":
+ """Limit number of results."""
+ ...
+
+ def offset(self, n: int) -> "ProjectGroupQuery":
+ """Skip first n results."""
+ ...
+
+ def distinct(self, value: bool = True) -> "ProjectGroupQuery":
+ """Return distinct results."""
+ ...
+
+ def select(self, *fields: Literal["created_at", "description", "id", "name", "project", "project_id", "updated_at"]) -> "ProjectGroupQuery": # type: ignore[override]
+ """Select specific fields."""
+ ...
+
+ def join(self, *paths: str) -> "ProjectGroupQuery":
+ """Perform LEFT JOIN for relations."""
+ ...
+
+ def prefetch(self, *paths: str) -> "ProjectGroupQuery":
+ """Prefetch related objects (separate queries)."""
+ ...
+
+ def for_update(self) -> "ProjectGroupQuery":
+ """Add FOR UPDATE lock to query."""
+ ...
+
+ def for_share(self) -> "ProjectGroupQuery":
+ """Add FOR SHARE lock to query."""
+ ...
+
+ def annotate(self, **annotations: Any) -> "ProjectGroupQuery":
+ """Add computed fields using aggregate functions."""
+ ...
+
+ def group_by(self, *fields: Literal["created_at", "description", "id", "name", "project", "project_id", "updated_at"]) -> "ProjectGroupQuery": # type: ignore[override]
+ """Add GROUP BY clause."""
+ ...
+
+ def having(self, *q_exprs: Any, **kwargs: Any) -> "ProjectGroupQuery":
+ """Add HAVING clause for filtering grouped results."""
+ ...
+
+ def values(self, *fields: Literal["created_at", "description", "id", "name", "project", "project_id", "updated_at"]) -> "ProjectGroupQuery": # type: ignore[override]
+ """Return dicts instead of models."""
+ ...
+
+ def values_list(self, *fields: Literal["created_at", "description", "id", "name", "project", "project_id", "updated_at"], flat: bool = False) -> "ProjectGroupQuery": # type: ignore[override]
+ """Return tuples/values instead of models."""
+ ...
+
+ # Terminal methods (async, execute query)
+
+ async def all(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> list[ProjectGroup]:
+ """Execute query and return all results."""
+ ...
+
+ async def first(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> ProjectGroup | None:
+ """Execute query and return first result."""
+ ...
+
+ async def last(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> ProjectGroup | None:
+ """Execute query and return last result."""
+ ...
+
+ async def count(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> int:
+ """Count matching objects."""
+ ...
+
+ async def sum(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Calculate sum of field values."""
+ ...
+
+ async def avg(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Calculate average of field values."""
+ ...
+
+ async def max(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Get maximum field value."""
+ ...
+
+ async def min(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Get minimum field value."""
+ ...
+
+ async def update( # type: ignore[override]
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ **values: Any,
+ ) -> int:
+ """Update matching objects."""
+ ...
+
+ async def increment(
+ self,
+ field: str,
+ by: int | float = 1,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> int:
+ """Atomically increment a field value."""
+ ...
+
+ async def delete(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> int:
+ """Delete matching objects."""
+ ...
+
+class ProjectGroupManager(QueryManager[ProjectGroup]):
+ """Type-safe Manager for ProjectGroup model."""
+
+ # Query building methods (sync, return Query)
+
+ def query(self) -> ProjectGroupQuery:
+ """Return a Query builder for this model."""
+ ...
+
+ def filter(
+ self,
+ *args: Any,
+ created_at: datetime | None = None,
+ created_at__gt: datetime | None = None,
+ created_at__gte: datetime | None = None,
+ created_at__lt: datetime | None = None,
+ created_at__lte: datetime | None = None,
+ created_at__between: tuple[datetime, datetime] | None = None,
+ created_at__range: datetime | None = None,
+ created_at__year: int | None = None,
+ created_at__month: int | None = None,
+ created_at__day: int | None = None,
+ created_at__in: list[datetime] | None = None,
+ created_at__isnull: bool | None = None,
+ description: str | None = None,
+ description__contains: str | None = None,
+ description__icontains: str | None = None,
+ description__startswith: str | None = None,
+ description__istartswith: str | None = None,
+ description__endswith: str | None = None,
+ description__iendswith: str | None = None,
+ description__iexact: str | None = None,
+ description__in: list[str] | None = None,
+ description__isnull: bool | None = None,
+ id: int | None = None,
+ id__gt: int | None = None,
+ id__gte: int | None = None,
+ id__lt: int | None = None,
+ id__lte: int | None = None,
+ id__between: tuple[int, int] | None = None,
+ id__range: int | None = None,
+ id__in: list[int] | None = None,
+ id__isnull: bool | None = None,
+ name: str | None = None,
+ name__contains: str | None = None,
+ name__icontains: str | None = None,
+ name__startswith: str | None = None,
+ name__istartswith: str | None = None,
+ name__endswith: str | None = None,
+ name__iendswith: str | None = None,
+ name__iexact: str | None = None,
+ name__in: list[str] | None = None,
+ name__isnull: bool | None = None,
+ project: Project | None = None,
+ project__in: list[Project] | None = None,
+ project__isnull: bool | None = None,
+ project_id: int | None = None,
+ project_id__gt: int | None = None,
+ project_id__gte: int | None = None,
+ project_id__lt: int | None = None,
+ project_id__lte: int | None = None,
+ project_id__between: tuple[int, int] | None = None,
+ project_id__range: int | None = None,
+ project_id__in: list[int] | None = None,
+ project_id__isnull: bool | None = None,
+ updated_at: datetime | None = None,
+ updated_at__gt: datetime | None = None,
+ updated_at__gte: datetime | None = None,
+ updated_at__lt: datetime | None = None,
+ updated_at__lte: datetime | None = None,
+ updated_at__between: tuple[datetime, datetime] | None = None,
+ updated_at__range: datetime | None = None,
+ updated_at__year: int | None = None,
+ updated_at__month: int | None = None,
+ updated_at__day: int | None = None,
+ updated_at__in: list[datetime] | None = None,
+ updated_at__isnull: bool | None = None,
+ ) -> ProjectGroupQuery:
+ """Filter by Q-expressions or field lookups."""
+ ...
+
+ def exclude(
+ self,
+ *args: Any,
+ created_at: datetime | None = None,
+ created_at__gt: datetime | None = None,
+ created_at__gte: datetime | None = None,
+ created_at__lt: datetime | None = None,
+ created_at__lte: datetime | None = None,
+ created_at__between: tuple[datetime, datetime] | None = None,
+ created_at__range: datetime | None = None,
+ created_at__year: int | None = None,
+ created_at__month: int | None = None,
+ created_at__day: int | None = None,
+ created_at__in: list[datetime] | None = None,
+ created_at__isnull: bool | None = None,
+ description: str | None = None,
+ description__contains: str | None = None,
+ description__icontains: str | None = None,
+ description__startswith: str | None = None,
+ description__istartswith: str | None = None,
+ description__endswith: str | None = None,
+ description__iendswith: str | None = None,
+ description__iexact: str | None = None,
+ description__in: list[str] | None = None,
+ description__isnull: bool | None = None,
+ id: int | None = None,
+ id__gt: int | None = None,
+ id__gte: int | None = None,
+ id__lt: int | None = None,
+ id__lte: int | None = None,
+ id__between: tuple[int, int] | None = None,
+ id__range: int | None = None,
+ id__in: list[int] | None = None,
+ id__isnull: bool | None = None,
+ name: str | None = None,
+ name__contains: str | None = None,
+ name__icontains: str | None = None,
+ name__startswith: str | None = None,
+ name__istartswith: str | None = None,
+ name__endswith: str | None = None,
+ name__iendswith: str | None = None,
+ name__iexact: str | None = None,
+ name__in: list[str] | None = None,
+ name__isnull: bool | None = None,
+ project: Project | None = None,
+ project__in: list[Project] | None = None,
+ project__isnull: bool | None = None,
+ project_id: int | None = None,
+ project_id__gt: int | None = None,
+ project_id__gte: int | None = None,
+ project_id__lt: int | None = None,
+ project_id__lte: int | None = None,
+ project_id__between: tuple[int, int] | None = None,
+ project_id__range: int | None = None,
+ project_id__in: list[int] | None = None,
+ project_id__isnull: bool | None = None,
+ updated_at: datetime | None = None,
+ updated_at__gt: datetime | None = None,
+ updated_at__gte: datetime | None = None,
+ updated_at__lt: datetime | None = None,
+ updated_at__lte: datetime | None = None,
+ updated_at__between: tuple[datetime, datetime] | None = None,
+ updated_at__range: datetime | None = None,
+ updated_at__year: int | None = None,
+ updated_at__month: int | None = None,
+ updated_at__day: int | None = None,
+ updated_at__in: list[datetime] | None = None,
+ updated_at__isnull: bool | None = None,
+ ) -> ProjectGroupQuery:
+ """Exclude objects matching field lookups."""
+ ...
+
+ def values(self, *fields: Literal["created_at", "description", "id", "name", "project", "project_id", "updated_at"]) -> ProjectGroupQuery: # type: ignore[override]
+ """Return dicts instead of models."""
+ ...
+
+ def values_list(self, *fields: Literal["created_at", "description", "id", "name", "project", "project_id", "updated_at"], flat: bool = False) -> ProjectGroupQuery: # type: ignore[override]
+ """Return tuples/values instead of models."""
+ ...
+
+ def distinct(self, distinct: bool = True) -> ProjectGroupQuery:
+ """Return distinct results."""
+ ...
+
+ def join(self, *paths: str) -> ProjectGroupQuery:
+ """Perform LEFT JOIN for relations."""
+ ...
+
+ def prefetch(self, *paths: str) -> ProjectGroupQuery:
+ """Prefetch related objects (separate queries)."""
+ ...
+
+ def for_update(self) -> ProjectGroupQuery:
+ """Add FOR UPDATE lock to query."""
+ ...
+
+ def for_share(self) -> ProjectGroupQuery:
+ """Add FOR SHARE lock to query."""
+ ...
+
+ # Terminal methods (async, execute query)
+
+ async def get(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ **filters: Any,
+ ) -> ProjectGroup:
+ """Get single object matching lookups."""
+ ...
+
+ async def get_or_none(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ **filters: Any,
+ ) -> ProjectGroup | None:
+ """Get object or None if not found."""
+ ...
+
+ async def get_or_create(
+ self,
+ *,
+ defaults: dict[str, Any] | None = None,
+ client: Any | None = None,
+ using: str | None = None,
+ **filters: Any,
+ ) -> tuple[ProjectGroup, bool]:
+ """Get object or create if not found. Returns (object, created)."""
+ ...
+
+ async def update_or_create(
+ self,
+ *,
+ defaults: dict[str, Any] | None = None,
+ client: Any | None = None,
+ using: str | None = None,
+ **filters: Any,
+ ) -> tuple[ProjectGroup, bool]:
+ """Get object, create if missing, or update it when defaults are provided."""
+ ...
+
+ async def all(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ mode: str = "models",
+ ) -> list[ProjectGroup]:
+ """Get all objects."""
+ ...
+
+ async def first(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> ProjectGroup | None:
+ """Get first object."""
+ ...
+
+ async def last(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> ProjectGroup | None:
+ """Get last object."""
+ ...
+
+ async def count(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> int:
+ """Count all objects."""
+ ...
+
+ async def sum(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Calculate sum of field values."""
+ ...
+
+ async def avg(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Calculate average of field values."""
+ ...
+
+ async def max(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Get maximum field value."""
+ ...
+
+ async def min(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Get minimum field value."""
+ ...
+
+ async def create( # type: ignore[override]
+ self,
+ *,
+ instance: ProjectGroup | None = None,
+ client: Any | None = None,
+ using: str | None = None,
+ created_at: datetime | None = None,
+ description: str | None = None,
+ id: int | None = None,
+ name: str | None = None,
+ project: Project | None = None,
+ project_id: int | None = None,
+ updated_at: datetime | None = None,
+ ) -> ProjectGroup:
+ """Create new object."""
+ ...
+
+ async def bulk_create( # type: ignore[override]
+ self,
+ objects: list[ProjectGroup],
+ *,
+ batch_size: int | None = None,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> list[ProjectGroup]:
+ """Bulk create objects."""
+ ...
+
+ async def bulk_update( # type: ignore[override]
+ self,
+ objects: list[ProjectGroup],
+ fields: list[str],
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> int:
+ """Bulk update objects."""
+ ...
+
+
+class ProjectGroupPermission(Model):
+ class Meta:
+ is_table: bool
+ table_name: str
+ id: int | None
+ group: ProjectGroup | None
+ permission: str
+ group_id: int | None
+ objects: ClassVar["ProjectGroupPermissionManager"]
+
+
+class ProjectGroupPermissionQuery(Query[ProjectGroupPermission]):
+ """Type-safe Query for ProjectGroupPermission model."""
+
+ # Query building methods (sync, return Query)
+
+ def filter(
+ self,
+ *args: Any,
+ group: ProjectGroup | None = None,
+ group__in: list[ProjectGroup] | None = None,
+ group__isnull: bool | None = None,
+ group_id: int | None = None,
+ group_id__gt: int | None = None,
+ group_id__gte: int | None = None,
+ group_id__lt: int | None = None,
+ group_id__lte: int | None = None,
+ group_id__between: tuple[int, int] | None = None,
+ group_id__range: int | None = None,
+ group_id__in: list[int] | None = None,
+ group_id__isnull: bool | None = None,
+ id: int | None = None,
+ id__gt: int | None = None,
+ id__gte: int | None = None,
+ id__lt: int | None = None,
+ id__lte: int | None = None,
+ id__between: tuple[int, int] | None = None,
+ id__range: int | None = None,
+ id__in: list[int] | None = None,
+ id__isnull: bool | None = None,
+ permission: str | None = None,
+ permission__contains: str | None = None,
+ permission__icontains: str | None = None,
+ permission__startswith: str | None = None,
+ permission__istartswith: str | None = None,
+ permission__endswith: str | None = None,
+ permission__iendswith: str | None = None,
+ permission__iexact: str | None = None,
+ permission__in: list[str] | None = None,
+ permission__isnull: bool | None = None,
+ ) -> "ProjectGroupPermissionQuery":
+ """Filter by Q-expressions or field lookups."""
+ ...
+
+ def exclude(
+ self,
+ *args: Any,
+ group: ProjectGroup | None = None,
+ group__in: list[ProjectGroup] | None = None,
+ group__isnull: bool | None = None,
+ group_id: int | None = None,
+ group_id__gt: int | None = None,
+ group_id__gte: int | None = None,
+ group_id__lt: int | None = None,
+ group_id__lte: int | None = None,
+ group_id__between: tuple[int, int] | None = None,
+ group_id__range: int | None = None,
+ group_id__in: list[int] | None = None,
+ group_id__isnull: bool | None = None,
+ id: int | None = None,
+ id__gt: int | None = None,
+ id__gte: int | None = None,
+ id__lt: int | None = None,
+ id__lte: int | None = None,
+ id__between: tuple[int, int] | None = None,
+ id__range: int | None = None,
+ id__in: list[int] | None = None,
+ id__isnull: bool | None = None,
+ permission: str | None = None,
+ permission__contains: str | None = None,
+ permission__icontains: str | None = None,
+ permission__startswith: str | None = None,
+ permission__istartswith: str | None = None,
+ permission__endswith: str | None = None,
+ permission__iendswith: str | None = None,
+ permission__iexact: str | None = None,
+ permission__in: list[str] | None = None,
+ permission__isnull: bool | None = None,
+ ) -> "ProjectGroupPermissionQuery":
+ """Exclude objects matching field lookups."""
+ ...
+
+ def order_by(self, *fields: Literal["group", "-group", "group_id", "-group_id", "id", "-id", "permission", "-permission"]) -> "ProjectGroupPermissionQuery": # type: ignore[override]
+ """Order results by fields."""
+ ...
+
+ def limit(self, n: int) -> "ProjectGroupPermissionQuery":
+ """Limit number of results."""
+ ...
+
+ def offset(self, n: int) -> "ProjectGroupPermissionQuery":
+ """Skip first n results."""
+ ...
+
+ def distinct(self, value: bool = True) -> "ProjectGroupPermissionQuery":
+ """Return distinct results."""
+ ...
+
+ def select(self, *fields: Literal["group", "group_id", "id", "permission"]) -> "ProjectGroupPermissionQuery": # type: ignore[override]
+ """Select specific fields."""
+ ...
+
+ def join(self, *paths: str) -> "ProjectGroupPermissionQuery":
+ """Perform LEFT JOIN for relations."""
+ ...
+
+ def prefetch(self, *paths: str) -> "ProjectGroupPermissionQuery":
+ """Prefetch related objects (separate queries)."""
+ ...
+
+ def for_update(self) -> "ProjectGroupPermissionQuery":
+ """Add FOR UPDATE lock to query."""
+ ...
+
+ def for_share(self) -> "ProjectGroupPermissionQuery":
+ """Add FOR SHARE lock to query."""
+ ...
+
+ def annotate(self, **annotations: Any) -> "ProjectGroupPermissionQuery":
+ """Add computed fields using aggregate functions."""
+ ...
+
+ def group_by(self, *fields: Literal["group", "group_id", "id", "permission"]) -> "ProjectGroupPermissionQuery": # type: ignore[override]
+ """Add GROUP BY clause."""
+ ...
+
+ def having(self, *q_exprs: Any, **kwargs: Any) -> "ProjectGroupPermissionQuery":
+ """Add HAVING clause for filtering grouped results."""
+ ...
+
+ def values(self, *fields: Literal["group", "group_id", "id", "permission"]) -> "ProjectGroupPermissionQuery": # type: ignore[override]
+ """Return dicts instead of models."""
+ ...
+
+ def values_list(self, *fields: Literal["group", "group_id", "id", "permission"], flat: bool = False) -> "ProjectGroupPermissionQuery": # type: ignore[override]
+ """Return tuples/values instead of models."""
+ ...
+
+ # Terminal methods (async, execute query)
+
+ async def all(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> list[ProjectGroupPermission]:
+ """Execute query and return all results."""
+ ...
+
+ async def first(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> ProjectGroupPermission | None:
+ """Execute query and return first result."""
+ ...
+
+ async def last(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> ProjectGroupPermission | None:
+ """Execute query and return last result."""
+ ...
+
+ async def count(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> int:
+ """Count matching objects."""
+ ...
+
+ async def sum(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Calculate sum of field values."""
+ ...
+
+ async def avg(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Calculate average of field values."""
+ ...
+
+ async def max(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Get maximum field value."""
+ ...
+
+ async def min(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Get minimum field value."""
+ ...
+
+ async def update( # type: ignore[override]
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ **values: Any,
+ ) -> int:
+ """Update matching objects."""
+ ...
+
+ async def increment(
+ self,
+ field: str,
+ by: int | float = 1,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> int:
+ """Atomically increment a field value."""
+ ...
+
+ async def delete(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> int:
+ """Delete matching objects."""
+ ...
+
+class ProjectGroupPermissionManager(QueryManager[ProjectGroupPermission]):
+ """Type-safe Manager for ProjectGroupPermission model."""
+
+ # Query building methods (sync, return Query)
+
+ def query(self) -> ProjectGroupPermissionQuery:
+ """Return a Query builder for this model."""
+ ...
+
+ def filter(
+ self,
+ *args: Any,
+ group: ProjectGroup | None = None,
+ group__in: list[ProjectGroup] | None = None,
+ group__isnull: bool | None = None,
+ group_id: int | None = None,
+ group_id__gt: int | None = None,
+ group_id__gte: int | None = None,
+ group_id__lt: int | None = None,
+ group_id__lte: int | None = None,
+ group_id__between: tuple[int, int] | None = None,
+ group_id__range: int | None = None,
+ group_id__in: list[int] | None = None,
+ group_id__isnull: bool | None = None,
+ id: int | None = None,
+ id__gt: int | None = None,
+ id__gte: int | None = None,
+ id__lt: int | None = None,
+ id__lte: int | None = None,
+ id__between: tuple[int, int] | None = None,
+ id__range: int | None = None,
+ id__in: list[int] | None = None,
+ id__isnull: bool | None = None,
+ permission: str | None = None,
+ permission__contains: str | None = None,
+ permission__icontains: str | None = None,
+ permission__startswith: str | None = None,
+ permission__istartswith: str | None = None,
+ permission__endswith: str | None = None,
+ permission__iendswith: str | None = None,
+ permission__iexact: str | None = None,
+ permission__in: list[str] | None = None,
+ permission__isnull: bool | None = None,
+ ) -> ProjectGroupPermissionQuery:
+ """Filter by Q-expressions or field lookups."""
+ ...
+
+ def exclude(
+ self,
+ *args: Any,
+ group: ProjectGroup | None = None,
+ group__in: list[ProjectGroup] | None = None,
+ group__isnull: bool | None = None,
+ group_id: int | None = None,
+ group_id__gt: int | None = None,
+ group_id__gte: int | None = None,
+ group_id__lt: int | None = None,
+ group_id__lte: int | None = None,
+ group_id__between: tuple[int, int] | None = None,
+ group_id__range: int | None = None,
+ group_id__in: list[int] | None = None,
+ group_id__isnull: bool | None = None,
+ id: int | None = None,
+ id__gt: int | None = None,
+ id__gte: int | None = None,
+ id__lt: int | None = None,
+ id__lte: int | None = None,
+ id__between: tuple[int, int] | None = None,
+ id__range: int | None = None,
+ id__in: list[int] | None = None,
+ id__isnull: bool | None = None,
+ permission: str | None = None,
+ permission__contains: str | None = None,
+ permission__icontains: str | None = None,
+ permission__startswith: str | None = None,
+ permission__istartswith: str | None = None,
+ permission__endswith: str | None = None,
+ permission__iendswith: str | None = None,
+ permission__iexact: str | None = None,
+ permission__in: list[str] | None = None,
+ permission__isnull: bool | None = None,
+ ) -> ProjectGroupPermissionQuery:
+ """Exclude objects matching field lookups."""
+ ...
+
+ def values(self, *fields: Literal["group", "group_id", "id", "permission"]) -> ProjectGroupPermissionQuery: # type: ignore[override]
+ """Return dicts instead of models."""
+ ...
+
+ def values_list(self, *fields: Literal["group", "group_id", "id", "permission"], flat: bool = False) -> ProjectGroupPermissionQuery: # type: ignore[override]
+ """Return tuples/values instead of models."""
+ ...
+
+ def distinct(self, distinct: bool = True) -> ProjectGroupPermissionQuery:
+ """Return distinct results."""
+ ...
+
+ def join(self, *paths: str) -> ProjectGroupPermissionQuery:
+ """Perform LEFT JOIN for relations."""
+ ...
+
+ def prefetch(self, *paths: str) -> ProjectGroupPermissionQuery:
+ """Prefetch related objects (separate queries)."""
+ ...
+
+ def for_update(self) -> ProjectGroupPermissionQuery:
+ """Add FOR UPDATE lock to query."""
+ ...
+
+ def for_share(self) -> ProjectGroupPermissionQuery:
+ """Add FOR SHARE lock to query."""
+ ...
+
+ # Terminal methods (async, execute query)
+
+ async def get(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ **filters: Any,
+ ) -> ProjectGroupPermission:
+ """Get single object matching lookups."""
+ ...
+
+ async def get_or_none(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ **filters: Any,
+ ) -> ProjectGroupPermission | None:
+ """Get object or None if not found."""
+ ...
+
+ async def get_or_create(
+ self,
+ *,
+ defaults: dict[str, Any] | None = None,
+ client: Any | None = None,
+ using: str | None = None,
+ **filters: Any,
+ ) -> tuple[ProjectGroupPermission, bool]:
+ """Get object or create if not found. Returns (object, created)."""
+ ...
+
+ async def update_or_create(
+ self,
+ *,
+ defaults: dict[str, Any] | None = None,
+ client: Any | None = None,
+ using: str | None = None,
+ **filters: Any,
+ ) -> tuple[ProjectGroupPermission, bool]:
+ """Get object, create if missing, or update it when defaults are provided."""
+ ...
+
+ async def all(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ mode: str = "models",
+ ) -> list[ProjectGroupPermission]:
+ """Get all objects."""
+ ...
+
+ async def first(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> ProjectGroupPermission | None:
+ """Get first object."""
+ ...
+
+ async def last(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> ProjectGroupPermission | None:
+ """Get last object."""
+ ...
+
+ async def count(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> int:
+ """Count all objects."""
+ ...
+
+ async def sum(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Calculate sum of field values."""
+ ...
+
+ async def avg(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Calculate average of field values."""
+ ...
+
+ async def max(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Get maximum field value."""
+ ...
+
+ async def min(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Get minimum field value."""
+ ...
+
+ async def create( # type: ignore[override]
+ self,
+ *,
+ instance: ProjectGroupPermission | None = None,
+ client: Any | None = None,
+ using: str | None = None,
+ group: ProjectGroup | None = None,
+ group_id: int | None = None,
+ id: int | None = None,
+ permission: str | None = None,
+ ) -> ProjectGroupPermission:
+ """Create new object."""
+ ...
+
+ async def bulk_create( # type: ignore[override]
+ self,
+ objects: list[ProjectGroupPermission],
+ *,
+ batch_size: int | None = None,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> list[ProjectGroupPermission]:
+ """Bulk create objects."""
+ ...
+
+ async def bulk_update( # type: ignore[override]
+ self,
+ objects: list[ProjectGroupPermission],
+ fields: list[str],
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> int:
+ """Bulk update objects."""
+ ...
+
+
+class ProjectMember(Model):
+ class Meta:
+ is_table: bool
+ table_name: str
+ id: int | None
+ group: ProjectGroup | None
+ user: User | None
+ created_at: datetime | None
+ group_id: int | None
+ user_id: int | None
+ objects: ClassVar["ProjectMemberManager"]
+
+
+class ProjectMemberQuery(Query[ProjectMember]):
+ """Type-safe Query for ProjectMember model."""
+
+ # Query building methods (sync, return Query)
+
+ def filter(
+ self,
+ *args: Any,
+ created_at: datetime | None = None,
+ created_at__gt: datetime | None = None,
+ created_at__gte: datetime | None = None,
+ created_at__lt: datetime | None = None,
+ created_at__lte: datetime | None = None,
+ created_at__between: tuple[datetime, datetime] | None = None,
+ created_at__range: datetime | None = None,
+ created_at__year: int | None = None,
+ created_at__month: int | None = None,
+ created_at__day: int | None = None,
+ created_at__in: list[datetime] | None = None,
+ created_at__isnull: bool | None = None,
+ group: ProjectGroup | None = None,
+ group__in: list[ProjectGroup] | None = None,
+ group__isnull: bool | None = None,
+ group_id: int | None = None,
+ group_id__gt: int | None = None,
+ group_id__gte: int | None = None,
+ group_id__lt: int | None = None,
+ group_id__lte: int | None = None,
+ group_id__between: tuple[int, int] | None = None,
+ group_id__range: int | None = None,
+ group_id__in: list[int] | None = None,
+ group_id__isnull: bool | None = None,
+ id: int | None = None,
+ id__gt: int | None = None,
+ id__gte: int | None = None,
+ id__lt: int | None = None,
+ id__lte: int | None = None,
+ id__between: tuple[int, int] | None = None,
+ id__range: int | None = None,
+ id__in: list[int] | None = None,
+ id__isnull: bool | None = None,
+ user: User | None = None,
+ user__in: list[User] | None = None,
+ user__isnull: bool | None = None,
+ user_id: int | None = None,
+ user_id__gt: int | None = None,
+ user_id__gte: int | None = None,
+ user_id__lt: int | None = None,
+ user_id__lte: int | None = None,
+ user_id__between: tuple[int, int] | None = None,
+ user_id__range: int | None = None,
+ user_id__in: list[int] | None = None,
+ user_id__isnull: bool | None = None,
+ ) -> "ProjectMemberQuery":
+ """Filter by Q-expressions or field lookups."""
+ ...
+
+ def exclude(
+ self,
+ *args: Any,
+ created_at: datetime | None = None,
+ created_at__gt: datetime | None = None,
+ created_at__gte: datetime | None = None,
+ created_at__lt: datetime | None = None,
+ created_at__lte: datetime | None = None,
+ created_at__between: tuple[datetime, datetime] | None = None,
+ created_at__range: datetime | None = None,
+ created_at__year: int | None = None,
+ created_at__month: int | None = None,
+ created_at__day: int | None = None,
+ created_at__in: list[datetime] | None = None,
+ created_at__isnull: bool | None = None,
+ group: ProjectGroup | None = None,
+ group__in: list[ProjectGroup] | None = None,
+ group__isnull: bool | None = None,
+ group_id: int | None = None,
+ group_id__gt: int | None = None,
+ group_id__gte: int | None = None,
+ group_id__lt: int | None = None,
+ group_id__lte: int | None = None,
+ group_id__between: tuple[int, int] | None = None,
+ group_id__range: int | None = None,
+ group_id__in: list[int] | None = None,
+ group_id__isnull: bool | None = None,
+ id: int | None = None,
+ id__gt: int | None = None,
+ id__gte: int | None = None,
+ id__lt: int | None = None,
+ id__lte: int | None = None,
+ id__between: tuple[int, int] | None = None,
+ id__range: int | None = None,
+ id__in: list[int] | None = None,
+ id__isnull: bool | None = None,
+ user: User | None = None,
+ user__in: list[User] | None = None,
+ user__isnull: bool | None = None,
+ user_id: int | None = None,
+ user_id__gt: int | None = None,
+ user_id__gte: int | None = None,
+ user_id__lt: int | None = None,
+ user_id__lte: int | None = None,
+ user_id__between: tuple[int, int] | None = None,
+ user_id__range: int | None = None,
+ user_id__in: list[int] | None = None,
+ user_id__isnull: bool | None = None,
+ ) -> "ProjectMemberQuery":
+ """Exclude objects matching field lookups."""
+ ...
+
+ def order_by(self, *fields: Literal["created_at", "-created_at", "group", "-group", "group_id", "-group_id", "id", "-id", "user", "-user", "user_id", "-user_id"]) -> "ProjectMemberQuery": # type: ignore[override]
+ """Order results by fields."""
+ ...
+
+ def limit(self, n: int) -> "ProjectMemberQuery":
+ """Limit number of results."""
+ ...
+
+ def offset(self, n: int) -> "ProjectMemberQuery":
+ """Skip first n results."""
+ ...
+
+ def distinct(self, value: bool = True) -> "ProjectMemberQuery":
+ """Return distinct results."""
+ ...
+
+ def select(self, *fields: Literal["created_at", "group", "group_id", "id", "user", "user_id"]) -> "ProjectMemberQuery": # type: ignore[override]
+ """Select specific fields."""
+ ...
+
+ def join(self, *paths: str) -> "ProjectMemberQuery":
+ """Perform LEFT JOIN for relations."""
+ ...
+
+ def prefetch(self, *paths: str) -> "ProjectMemberQuery":
+ """Prefetch related objects (separate queries)."""
+ ...
+
+ def for_update(self) -> "ProjectMemberQuery":
+ """Add FOR UPDATE lock to query."""
+ ...
+
+ def for_share(self) -> "ProjectMemberQuery":
+ """Add FOR SHARE lock to query."""
+ ...
+
+ def annotate(self, **annotations: Any) -> "ProjectMemberQuery":
+ """Add computed fields using aggregate functions."""
+ ...
+
+ def group_by(self, *fields: Literal["created_at", "group", "group_id", "id", "user", "user_id"]) -> "ProjectMemberQuery": # type: ignore[override]
+ """Add GROUP BY clause."""
+ ...
+
+ def having(self, *q_exprs: Any, **kwargs: Any) -> "ProjectMemberQuery":
+ """Add HAVING clause for filtering grouped results."""
+ ...
+
+ def values(self, *fields: Literal["created_at", "group", "group_id", "id", "user", "user_id"]) -> "ProjectMemberQuery": # type: ignore[override]
+ """Return dicts instead of models."""
+ ...
+
+ def values_list(self, *fields: Literal["created_at", "group", "group_id", "id", "user", "user_id"], flat: bool = False) -> "ProjectMemberQuery": # type: ignore[override]
+ """Return tuples/values instead of models."""
+ ...
+
+ # Terminal methods (async, execute query)
+
+ async def all(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> list[ProjectMember]:
+ """Execute query and return all results."""
+ ...
+
+ async def first(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> ProjectMember | None:
+ """Execute query and return first result."""
+ ...
+
+ async def last(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> ProjectMember | None:
+ """Execute query and return last result."""
+ ...
+
+ async def count(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> int:
+ """Count matching objects."""
+ ...
+
+ async def sum(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Calculate sum of field values."""
+ ...
+
+ async def avg(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Calculate average of field values."""
+ ...
+
+ async def max(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Get maximum field value."""
+ ...
+
+ async def min(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Get minimum field value."""
+ ...
+
+ async def update( # type: ignore[override]
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ **values: Any,
+ ) -> int:
+ """Update matching objects."""
+ ...
+
+ async def increment(
+ self,
+ field: str,
+ by: int | float = 1,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> int:
+ """Atomically increment a field value."""
+ ...
+
+ async def delete(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> int:
+ """Delete matching objects."""
+ ...
+
+class ProjectMemberManager(QueryManager[ProjectMember]):
+ """Type-safe Manager for ProjectMember model."""
+
+ # Query building methods (sync, return Query)
+
+ def query(self) -> ProjectMemberQuery:
+ """Return a Query builder for this model."""
+ ...
+
+ def filter(
+ self,
+ *args: Any,
+ created_at: datetime | None = None,
+ created_at__gt: datetime | None = None,
+ created_at__gte: datetime | None = None,
+ created_at__lt: datetime | None = None,
+ created_at__lte: datetime | None = None,
+ created_at__between: tuple[datetime, datetime] | None = None,
+ created_at__range: datetime | None = None,
+ created_at__year: int | None = None,
+ created_at__month: int | None = None,
+ created_at__day: int | None = None,
+ created_at__in: list[datetime] | None = None,
+ created_at__isnull: bool | None = None,
+ group: ProjectGroup | None = None,
+ group__in: list[ProjectGroup] | None = None,
+ group__isnull: bool | None = None,
+ group_id: int | None = None,
+ group_id__gt: int | None = None,
+ group_id__gte: int | None = None,
+ group_id__lt: int | None = None,
+ group_id__lte: int | None = None,
+ group_id__between: tuple[int, int] | None = None,
+ group_id__range: int | None = None,
+ group_id__in: list[int] | None = None,
+ group_id__isnull: bool | None = None,
+ id: int | None = None,
+ id__gt: int | None = None,
+ id__gte: int | None = None,
+ id__lt: int | None = None,
+ id__lte: int | None = None,
+ id__between: tuple[int, int] | None = None,
+ id__range: int | None = None,
+ id__in: list[int] | None = None,
+ id__isnull: bool | None = None,
+ user: User | None = None,
+ user__in: list[User] | None = None,
+ user__isnull: bool | None = None,
+ user_id: int | None = None,
+ user_id__gt: int | None = None,
+ user_id__gte: int | None = None,
+ user_id__lt: int | None = None,
+ user_id__lte: int | None = None,
+ user_id__between: tuple[int, int] | None = None,
+ user_id__range: int | None = None,
+ user_id__in: list[int] | None = None,
+ user_id__isnull: bool | None = None,
+ ) -> ProjectMemberQuery:
+ """Filter by Q-expressions or field lookups."""
+ ...
+
+ def exclude(
+ self,
+ *args: Any,
+ created_at: datetime | None = None,
+ created_at__gt: datetime | None = None,
+ created_at__gte: datetime | None = None,
+ created_at__lt: datetime | None = None,
+ created_at__lte: datetime | None = None,
+ created_at__between: tuple[datetime, datetime] | None = None,
+ created_at__range: datetime | None = None,
+ created_at__year: int | None = None,
+ created_at__month: int | None = None,
+ created_at__day: int | None = None,
+ created_at__in: list[datetime] | None = None,
+ created_at__isnull: bool | None = None,
+ group: ProjectGroup | None = None,
+ group__in: list[ProjectGroup] | None = None,
+ group__isnull: bool | None = None,
+ group_id: int | None = None,
+ group_id__gt: int | None = None,
+ group_id__gte: int | None = None,
+ group_id__lt: int | None = None,
+ group_id__lte: int | None = None,
+ group_id__between: tuple[int, int] | None = None,
+ group_id__range: int | None = None,
+ group_id__in: list[int] | None = None,
+ group_id__isnull: bool | None = None,
+ id: int | None = None,
+ id__gt: int | None = None,
+ id__gte: int | None = None,
+ id__lt: int | None = None,
+ id__lte: int | None = None,
+ id__between: tuple[int, int] | None = None,
+ id__range: int | None = None,
+ id__in: list[int] | None = None,
+ id__isnull: bool | None = None,
+ user: User | None = None,
+ user__in: list[User] | None = None,
+ user__isnull: bool | None = None,
+ user_id: int | None = None,
+ user_id__gt: int | None = None,
+ user_id__gte: int | None = None,
+ user_id__lt: int | None = None,
+ user_id__lte: int | None = None,
+ user_id__between: tuple[int, int] | None = None,
+ user_id__range: int | None = None,
+ user_id__in: list[int] | None = None,
+ user_id__isnull: bool | None = None,
+ ) -> ProjectMemberQuery:
+ """Exclude objects matching field lookups."""
+ ...
+
+ def values(self, *fields: Literal["created_at", "group", "group_id", "id", "user", "user_id"]) -> ProjectMemberQuery: # type: ignore[override]
+ """Return dicts instead of models."""
+ ...
+
+ def values_list(self, *fields: Literal["created_at", "group", "group_id", "id", "user", "user_id"], flat: bool = False) -> ProjectMemberQuery: # type: ignore[override]
+ """Return tuples/values instead of models."""
+ ...
+
+ def distinct(self, distinct: bool = True) -> ProjectMemberQuery:
+ """Return distinct results."""
+ ...
+
+ def join(self, *paths: str) -> ProjectMemberQuery:
+ """Perform LEFT JOIN for relations."""
+ ...
+
+ def prefetch(self, *paths: str) -> ProjectMemberQuery:
+ """Prefetch related objects (separate queries)."""
+ ...
+
+ def for_update(self) -> ProjectMemberQuery:
+ """Add FOR UPDATE lock to query."""
+ ...
+
+ def for_share(self) -> ProjectMemberQuery:
+ """Add FOR SHARE lock to query."""
+ ...
+
+ # Terminal methods (async, execute query)
+
+ async def get(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ **filters: Any,
+ ) -> ProjectMember:
+ """Get single object matching lookups."""
+ ...
+
+ async def get_or_none(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ **filters: Any,
+ ) -> ProjectMember | None:
+ """Get object or None if not found."""
+ ...
+
+ async def get_or_create(
+ self,
+ *,
+ defaults: dict[str, Any] | None = None,
+ client: Any | None = None,
+ using: str | None = None,
+ **filters: Any,
+ ) -> tuple[ProjectMember, bool]:
+ """Get object or create if not found. Returns (object, created)."""
+ ...
+
+ async def update_or_create(
+ self,
+ *,
+ defaults: dict[str, Any] | None = None,
+ client: Any | None = None,
+ using: str | None = None,
+ **filters: Any,
+ ) -> tuple[ProjectMember, bool]:
+ """Get object, create if missing, or update it when defaults are provided."""
+ ...
+
+ async def all(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ mode: str = "models",
+ ) -> list[ProjectMember]:
+ """Get all objects."""
+ ...
+
+ async def first(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> ProjectMember | None:
+ """Get first object."""
+ ...
+
+ async def last(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> ProjectMember | None:
+ """Get last object."""
+ ...
+
+ async def count(
+ self,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> int:
+ """Count all objects."""
+ ...
+
+ async def sum(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Calculate sum of field values."""
+ ...
+
+ async def avg(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Calculate average of field values."""
+ ...
+
+ async def max(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Get maximum field value."""
+ ...
+
+ async def min(
+ self,
+ field: str,
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> Any:
+ """Get minimum field value."""
+ ...
+
+ async def create( # type: ignore[override]
+ self,
+ *,
+ instance: ProjectMember | None = None,
+ client: Any | None = None,
+ using: str | None = None,
+ created_at: datetime | None = None,
+ group: ProjectGroup | None = None,
+ group_id: int | None = None,
+ id: int | None = None,
+ user: User | None = None,
+ user_id: int | None = None,
+ ) -> ProjectMember:
+ """Create new object."""
+ ...
+
+ async def bulk_create( # type: ignore[override]
+ self,
+ objects: list[ProjectMember],
+ *,
+ batch_size: int | None = None,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> list[ProjectMember]:
+ """Bulk create objects."""
+ ...
+
+ async def bulk_update( # type: ignore[override]
+ self,
+ objects: list[ProjectMember],
+ fields: list[str],
+ *,
+ client: Any | None = None,
+ using: str | None = None,
+ ) -> int:
+ """Bulk update objects."""
+ ...
+
diff --git a/freenit/modules.py b/freenit/modules.py
index cb0f6cf..25df477 100644
--- a/freenit/modules.py
+++ b/freenit/modules.py
@@ -68,10 +68,10 @@ def __hash__(self):
dependencies=["user"],
api="freenit.api.sieve",
),
- "jabber": Module(
- name="jabber",
+ "chat": Module(
+ name="chat",
dependencies=["user"],
- api="freenit.api.jabber",
+ api="freenit.api.chat",
),
"omemo": Module(
name="omemo",
@@ -84,6 +84,12 @@ def __hash__(self):
models=["freenit.models.sql.git"],
api="freenit.api.git",
),
+ "blog": Module(
+ name="blog",
+ dependencies=["user"],
+ models=["freenit.models.sql.blog"],
+ api="freenit.api.blog",
+ ),
}
diff --git a/freenit/permissions.py b/freenit/permissions.py
index 4e789c3..d664b33 100644
--- a/freenit/permissions.py
+++ b/freenit/permissions.py
@@ -9,3 +9,4 @@
project_perms = permissions()
role_perms = permissions()
user_perms = permissions()
+blog_perms = permissions()
diff --git a/freenit/project/tests/test_git.py b/freenit/project/tests/test_git.py
index af7fc40..1324ff0 100644
--- a/freenit/project/tests/test_git.py
+++ b/freenit/project/tests/test_git.py
@@ -3,7 +3,7 @@
from pathlib import Path
import io
-from unittest.mock import patch
+from unittest.mock import AsyncMock, patch
import pytest
from fastapi.testclient import TestClient
@@ -454,3 +454,111 @@ async def test_post_receive_ignores_task_refs_outside_project(self, client):
response = client.get(f"/git/repos/{repo_id}/task-refs")
assert response.status_code == 200 # nosec
assert response.json()["total"] == 0 # nosec
+
+ @pytest.mark.asyncio
+ async def test_hook_push_endpoint_sends_webhook(self, client):
+ admin: User = factories.User(admin=True)
+ await admin.save()
+ client.login(user=admin)
+ project_id = _create_project(client)
+
+ response = client.post(
+ "/git/repos",
+ {
+ "name": "webhook-repo",
+ "path": _tmp_dir(),
+ "project_id": project_id,
+ "webhook_url": "https://example.com/hook",
+ },
+ )
+ repo_id = response.json()["id"]
+
+ with patch("freenit.api.git.notify_push") as mock_notify:
+ response = client.post(
+ f"/git/repos/{repo_id}/hooks/push",
+ {
+ "ref": "refs/heads/main",
+ "old_rev": "0000000000000000000000000000000000000000",
+ "new_rev": "a" * 40,
+ "pusher_email": "pusher@example.com",
+ },
+ )
+ assert response.status_code == 200 # nosec
+ mock_notify.assert_awaited_once()
+ args = mock_notify.await_args.args
+ assert args[0].id == repo_id # nosec
+ assert args[1] == "refs/heads/main" # nosec
+
+ @pytest.mark.asyncio
+ async def test_post_receive_sends_webhook(self, client):
+ admin: User = factories.User(admin=True)
+ await admin.save()
+ client.login(user=admin)
+ project_id = _create_project(client)
+ tmp = _init_temp_repo()
+
+ response = client.post(
+ "/git/repos",
+ {
+ "name": "post-webhook-repo",
+ "path": tmp.name,
+ "project_id": project_id,
+ "webhook_url": "https://example.com/hook",
+ },
+ )
+ repo_id = response.json()["id"]
+
+ proc = subprocess.run(
+ ["git", "-C", tmp.name, "rev-parse", "HEAD"],
+ capture_output=True,
+ text=True,
+ check=True,
+ ) # nosec
+ head = proc.stdout.strip()
+
+ stdin_data = f"0000000000000000000000000000000000000000 {head} refs/heads/main\n"
+ with patch("freenit.git.hooks.notify_push") as mock_notify:
+ with patch("sys.stdin", io.StringIO(stdin_data)):
+ result = await post_receive("post-webhook-repo")
+ assert result == 0 # nosec
+ mock_notify.assert_awaited_once()
+ args = mock_notify.await_args.args
+ assert args[0].id == repo_id # nosec
+ assert args[1] == "refs/heads/main" # nosec
+
+ @pytest.mark.asyncio
+ async def test_webhook_payload(self):
+ from freenit.git.webhook import notify_push
+
+ repo = AsyncMock()
+ repo.id = 1
+ repo.name = "payload-repo"
+ repo.path = None
+ repo.webhook_url = "https://example.com/hook"
+
+ from unittest.mock import Mock
+
+ mock_response = AsyncMock()
+ mock_response.raise_for_status = Mock()
+ mock_client = AsyncMock()
+ mock_client.post = AsyncMock(return_value=mock_response)
+ mock_client.__aenter__ = AsyncMock(return_value=mock_client)
+ mock_client.__aexit__ = AsyncMock(return_value=False)
+
+ with patch("freenit.git.webhook.httpx.AsyncClient", return_value=mock_client):
+ await notify_push(
+ repo,
+ "refs/heads/main",
+ "0" * 40,
+ "a" * 40,
+ "pusher@example.com",
+ )
+
+ mock_client.post.assert_awaited_once()
+ url, kwargs = mock_client.post.await_args.args, mock_client.post.await_args.kwargs
+ assert url[0] == "https://example.com/hook" # nosec
+ payload = kwargs["json"]
+ assert payload["event"] == "push" # nosec
+ assert payload["repository"]["name"] == "payload-repo" # nosec
+ assert payload["ref"] == "refs/heads/main" # nosec
+ assert payload["pusher"]["email"] == "pusher@example.com" # nosec
diff --git a/migrations/0007_add_git.py b/migrations/0007_add_git.py
index 9de5907..1f31d8c 100644
--- a/migrations/0007_add_git.py
+++ b/migrations/0007_add_git.py
@@ -128,6 +128,19 @@ def upgrade(ctx):
"max_digits": None,
"decimal_places": None,
},
+ {
+ "name": "webhook_url",
+ "python_type": "str",
+ "db_type": None,
+ "nullable": True,
+ "primary_key": False,
+ "unique": False,
+ "default": None,
+ "auto_increment": False,
+ "max_length": None,
+ "max_digits": None,
+ "decimal_places": None,
+ },
{
"name": "created_at",
"python_type": "datetime",
diff --git a/migrations/0008_add_blog.py b/migrations/0008_add_blog.py
new file mode 100644
index 0000000..b5fbffc
--- /dev/null
+++ b/migrations/0008_add_blog.py
@@ -0,0 +1,268 @@
+"""Add blog tables.
+
+Created: 2026-06-29 00:00:00
+"""
+
+depends_on = "0007_add_git"
+
+
+def upgrade(ctx):
+ """Apply migration."""
+ ctx.create_table(
+ "blog_tag",
+ fields=[
+ {
+ "name": "id",
+ "python_type": "int",
+ "db_type": None,
+ "nullable": True,
+ "primary_key": True,
+ "unique": False,
+ "default": None,
+ "auto_increment": False,
+ "max_length": None,
+ "max_digits": None,
+ "decimal_places": None,
+ },
+ {
+ "name": "name",
+ "python_type": "str",
+ "db_type": None,
+ "nullable": False,
+ "primary_key": False,
+ "unique": False,
+ "default": None,
+ "auto_increment": False,
+ "max_length": None,
+ "max_digits": None,
+ "decimal_places": None,
+ },
+ ],
+ indexes=[
+ {
+ "name": "idx_blog_tag_name",
+ "fields": ["name"],
+ "unique": True,
+ }
+ ],
+ )
+ ctx.create_table(
+ "blog_post",
+ fields=[
+ {
+ "name": "id",
+ "python_type": "int",
+ "db_type": None,
+ "nullable": True,
+ "primary_key": True,
+ "unique": False,
+ "default": None,
+ "auto_increment": False,
+ "max_length": None,
+ "max_digits": None,
+ "decimal_places": None,
+ },
+ {
+ "name": "title",
+ "python_type": "str",
+ "db_type": None,
+ "nullable": False,
+ "primary_key": False,
+ "unique": False,
+ "default": None,
+ "auto_increment": False,
+ "max_length": None,
+ "max_digits": None,
+ "decimal_places": None,
+ },
+ {
+ "name": "slug",
+ "python_type": "str",
+ "db_type": None,
+ "nullable": False,
+ "primary_key": False,
+ "unique": False,
+ "default": None,
+ "auto_increment": False,
+ "max_length": None,
+ "max_digits": None,
+ "decimal_places": None,
+ },
+ {
+ "name": "content",
+ "python_type": "str",
+ "db_type": None,
+ "nullable": False,
+ "primary_key": False,
+ "unique": False,
+ "default": None,
+ "auto_increment": False,
+ "max_length": None,
+ "max_digits": None,
+ "decimal_places": None,
+ },
+ {
+ "name": "date",
+ "python_type": "datetime",
+ "db_type": None,
+ "nullable": True,
+ "primary_key": False,
+ "unique": False,
+ "default": None,
+ "auto_increment": False,
+ "max_length": None,
+ "max_digits": None,
+ "decimal_places": None,
+ },
+ {
+ "name": "published",
+ "python_type": "bool",
+ "db_type": None,
+ "nullable": False,
+ "primary_key": False,
+ "unique": False,
+ "default": "0",
+ "auto_increment": False,
+ "max_length": None,
+ "max_digits": None,
+ "decimal_places": None,
+ },
+ {
+ "name": "created_at",
+ "python_type": "datetime",
+ "db_type": None,
+ "nullable": True,
+ "primary_key": False,
+ "unique": False,
+ "default": None,
+ "auto_increment": False,
+ "max_length": None,
+ "max_digits": None,
+ "decimal_places": None,
+ },
+ {
+ "name": "updated_at",
+ "python_type": "datetime",
+ "db_type": None,
+ "nullable": True,
+ "primary_key": False,
+ "unique": False,
+ "default": None,
+ "auto_increment": False,
+ "max_length": None,
+ "max_digits": None,
+ "decimal_places": None,
+ },
+ {
+ "name": "author_id",
+ "python_type": "int",
+ "db_type": None,
+ "nullable": True,
+ "primary_key": False,
+ "unique": False,
+ "default": None,
+ "auto_increment": False,
+ "max_length": None,
+ "max_digits": None,
+ "decimal_places": None,
+ },
+ ],
+ foreign_keys=[
+ {
+ "name": "fk_blog_post_author_id",
+ "columns": ["author_id"],
+ "ref_table": "user",
+ "ref_columns": ["id"],
+ "on_delete": "SET NULL",
+ "on_update": "CASCADE",
+ }
+ ],
+ indexes=[
+ {
+ "name": "idx_blog_post_slug",
+ "fields": ["slug"],
+ "unique": True,
+ },
+ {
+ "name": "idx_blog_post_published",
+ "fields": ["published"],
+ "unique": False,
+ },
+ ],
+ )
+ ctx.create_table(
+ "blog_post_tag",
+ fields=[
+ {
+ "name": "id",
+ "python_type": "int",
+ "db_type": None,
+ "nullable": True,
+ "primary_key": True,
+ "unique": False,
+ "default": None,
+ "auto_increment": False,
+ "max_length": None,
+ "max_digits": None,
+ "decimal_places": None,
+ },
+ {
+ "name": "post_id",
+ "python_type": "int",
+ "db_type": None,
+ "nullable": True,
+ "primary_key": False,
+ "unique": False,
+ "default": None,
+ "auto_increment": False,
+ "max_length": None,
+ "max_digits": None,
+ "decimal_places": None,
+ },
+ {
+ "name": "tag_id",
+ "python_type": "int",
+ "db_type": None,
+ "nullable": True,
+ "primary_key": False,
+ "unique": False,
+ "default": None,
+ "auto_increment": False,
+ "max_length": None,
+ "max_digits": None,
+ "decimal_places": None,
+ },
+ ],
+ foreign_keys=[
+ {
+ "name": "fk_blog_post_tag_post_id",
+ "columns": ["post_id"],
+ "ref_table": "blog_post",
+ "ref_columns": ["id"],
+ "on_delete": "CASCADE",
+ "on_update": "CASCADE",
+ },
+ {
+ "name": "fk_blog_post_tag_tag_id",
+ "columns": ["tag_id"],
+ "ref_table": "blog_tag",
+ "ref_columns": ["id"],
+ "on_delete": "CASCADE",
+ "on_update": "CASCADE",
+ },
+ ],
+ indexes=[
+ {
+ "name": "idx_blog_post_tag_post_id_tag_id",
+ "fields": ["post_id", "tag_id"],
+ "unique": True,
+ }
+ ],
+ )
+
+
+def downgrade(ctx):
+ """Revert migration."""
+ ctx.drop_table("blog_post_tag")
+ ctx.drop_table("blog_post")
+ ctx.drop_table("blog_tag")
diff --git a/tests/factories.py b/tests/factories.py
index bd4d926..3ac6796 100644
--- a/tests/factories.py
+++ b/tests/factories.py
@@ -2,6 +2,7 @@
from passlib.hash import pbkdf2_sha256
from freenit.config import getConfig
+from freenit.models.blog import BlogPost, Tag
from freenit.models.lms import (
Course,
CourseGroup,
@@ -150,3 +151,22 @@ class Meta:
group_id = None
permission = "edit"
+
+
+class TagFactory(factory.Factory):
+ class Meta:
+ model = Tag
+
+ name = factory.Faker("pystr")
+
+
+class BlogPostFactory(factory.Factory):
+ class Meta:
+ model = BlogPost
+
+ title = factory.Faker("sentence")
+ slug = factory.Faker("pystr")
+ content = factory.Faker("paragraph")
+ date = factory.Faker("date_time")
+ published = True
+ author_id = None
diff --git a/tests/test_blog.py b/tests/test_blog.py
new file mode 100644
index 0000000..5c590ab
--- /dev/null
+++ b/tests/test_blog.py
@@ -0,0 +1,176 @@
+import pytest
+
+from freenit.models.blog import BlogPostTag
+
+from . import factories
+
+
+@pytest.mark.asyncio
+class TestBlogPost:
+ async def test_create_blog_post(self, client):
+ user = factories.User()
+ await user.save()
+ client.login(user=user)
+ data = {
+ "title": "Hello World",
+ "slug": "hello-world",
+ "content": "This is a blog post.",
+ "published": True,
+ "tags": ["news", "update"],
+ }
+ response = client.post("/blog", data=data)
+ assert response.status_code == 200
+ result = response.json()
+ assert result["title"] == data["title"]
+ assert result["slug"] == data["slug"]
+ assert result["content"] == data["content"]
+ assert result["published"] is True
+ assert result["author_id"] == user.id
+ assert sorted(result["tags"]) == ["news", "update"]
+
+ async def test_get_blog_posts(self, client):
+ user = factories.User()
+ await user.save()
+ client.login(user=user)
+ post = factories.BlogPostFactory(author_id=user.id)
+ await post.save()
+ response = client.get("/blog")
+ assert response.status_code == 200
+ assert response.json()["total"] >= 1
+
+ async def test_get_blog_post(self, client):
+ user = factories.User()
+ await user.save()
+ client.login(user=user)
+ post = factories.BlogPostFactory(author_id=user.id)
+ await post.save()
+ response = client.get(f"/blog/{post.id}")
+ assert response.status_code == 200
+ assert response.json()["id"] == post.id
+
+ async def test_update_blog_post(self, client):
+ user = factories.User()
+ await user.save()
+ client.login(user=user)
+ post = factories.BlogPostFactory(author_id=user.id)
+ await post.save()
+ data = {"title": "Updated Title", "tags": ["updated"]}
+ response = client.patch(f"/blog/{post.id}", data=data)
+ assert response.status_code == 200
+ result = response.json()
+ assert result["title"] == data["title"]
+ assert result["tags"] == ["updated"]
+
+ async def test_delete_blog_post(self, client):
+ user = factories.User()
+ await user.save()
+ client.login(user=user)
+ post = factories.BlogPostFactory(author_id=user.id)
+ await post.save()
+ response = client.delete(f"/blog/{post.id}")
+ assert response.status_code == 200
+ response = client.get(f"/blog/{post.id}")
+ assert response.status_code == 404
+
+ async def test_create_blog_post_duplicate_slug(self, client):
+ user = factories.User()
+ await user.save()
+ client.login(user=user)
+ post = factories.BlogPostFactory(slug="unique-slug", author_id=user.id)
+ await post.save()
+ response = client.post(
+ "/blog",
+ data={
+ "title": "Another",
+ "slug": "unique-slug",
+ "content": "content",
+ },
+ )
+ assert response.status_code == 409
+
+ async def test_non_author_cannot_edit_blog_post(self, client):
+ author = factories.User()
+ await author.save()
+ other = factories.User()
+ await other.save()
+ post = factories.BlogPostFactory(author_id=author.id)
+ await post.save()
+ client.login(user=other)
+ response = client.patch(f"/blog/{post.id}", data={"title": "Hacked"})
+ assert response.status_code == 403
+
+ async def test_public_blog_post_list(self, client):
+ user = factories.User()
+ await user.save()
+ client.login(user=user)
+ post = factories.BlogPostFactory(published=True, author_id=user.id)
+ await post.save()
+ client.cookies.clear()
+ response = client.get("/blog/public")
+ assert response.status_code == 200
+ assert response.json()["total"] >= 1
+
+ async def test_public_blog_post_detail(self, client):
+ user = factories.User()
+ await user.save()
+ client.login(user=user)
+ post = factories.BlogPostFactory(
+ slug="public-post", published=True, author_id=user.id
+ )
+ await post.save()
+ client.cookies.clear()
+ response = client.get("/blog/public/public-post")
+ assert response.status_code == 200
+ assert response.json()["slug"] == "public-post"
+
+ async def test_public_blog_post_detail_unpublished(self, client):
+ user = factories.User()
+ await user.save()
+ client.login(user=user)
+ post = factories.BlogPostFactory(
+ slug="draft-post", published=False, author_id=user.id
+ )
+ await post.save()
+ client.cookies.clear()
+ response = client.get("/blog/public/draft-post")
+ assert response.status_code == 404
+
+ async def test_blog_tags_list(self, client):
+ user = factories.User()
+ await user.save()
+ client.login(user=user)
+ tag = factories.TagFactory(name="python")
+ await tag.save()
+ response = client.get("/blog/tags")
+ assert response.status_code == 200
+ assert any(item["name"] == "python" for item in response.json())
+
+ async def test_blog_posts_by_tag(self, client):
+ user = factories.User()
+ await user.save()
+ client.login(user=user)
+ post = factories.BlogPostFactory(published=True, author_id=user.id)
+ await post.save()
+ tag = factories.TagFactory(name="python")
+ await tag.save()
+ link = BlogPostTag(post_id=post.id, tag_id=tag.id)
+ await link.save()
+ client.cookies.clear()
+ response = client.get("/blog/tags/python/posts")
+ assert response.status_code == 200
+ assert response.json()["total"] >= 1
+
+ async def test_blog_rss(self, client):
+ user = factories.User()
+ await user.save()
+ client.login(user=user)
+ post = factories.BlogPostFactory(
+ title="RSS Post", slug="rss-post", published=True, author_id=user.id
+ )
+ await post.save()
+ client.cookies.clear()
+ response = client.get("/blog/rss")
+ assert response.status_code == 200
+ assert "application/rss+xml" in response.headers["content-type"]
+ assert "" in response.text
+ assert "RSS Post" in response.text