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