Skip to content

Feat/builtin models types #2590

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
16 changes: 13 additions & 3 deletions django-stubs/contrib/admin/models.pyi
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
from typing import Any, ClassVar
from uuid import UUID

from django.contrib.auth.models import AbstractUser
from django.contrib.contenttypes.models import ContentType
from django.db import models
from django.db.models import QuerySet
from django.db.models.base import Model
from django.db.models.expressions import Combinable
from typing_extensions import deprecated

ADDITION: int
Expand All @@ -28,13 +31,20 @@ class LogEntryManager(models.Manager[LogEntry]):
queryset: QuerySet[Model],
action_flag: int,
change_message: str | list[Any] = "",
*,
# Commit 27b68bc, django https://github.com/django/django/pull/19233
single_object: bool = False,
) -> list[LogEntry] | LogEntry: ...

class LogEntry(models.Model):
id: models.AutoField
pk: models.AutoField
action_time: models.DateTimeField
user: models.ForeignKey
content_type: models.ForeignKey
object_id: models.TextField
user: models.ForeignKey[AbstractUser | Combinable, AbstractUser]
user_id: Any
content_type: models.ForeignKey[ContentType | Combinable | None, ContentType | None]
content_type_id: int | None
object_id: models.TextField[str | int | Combinable | None, str | None]
object_repr: models.CharField
action_flag: models.PositiveSmallIntegerField
change_message: models.TextField
Expand Down
3 changes: 2 additions & 1 deletion django-stubs/contrib/auth/base_user.pyi
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from collections.abc import Iterable
from datetime import date, datetime
from typing import Any, ClassVar, Literal, TypeVar, overload

from django.db import models
Expand All @@ -18,7 +19,7 @@ class AbstractBaseUser(models.Model):
REQUIRED_FIELDS: ClassVar[list[str]]

password = models.CharField(max_length=128)
last_login = models.DateTimeField(blank=True, null=True)
last_login = models.DateTimeField[str | datetime | date | Combinable, datetime | None](blank=True, null=True)
is_active: bool | BooleanField[bool | Combinable, bool]

def get_username(self) -> str: ...
Expand Down
64 changes: 57 additions & 7 deletions django-stubs/contrib/auth/models.pyi
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from collections.abc import Iterable
from typing import Any, ClassVar, Literal, TypeVar
from typing import Any, ClassVar, Literal, TypeVar, type_check_only

from django.contrib.auth.base_user import AbstractBaseUser as AbstractBaseUser
from django.contrib.auth.base_user import BaseUserManager as BaseUserManager
Expand All @@ -8,6 +8,8 @@ from django.contrib.contenttypes.models import ContentType
from django.db import models
from django.db.models import QuerySet
from django.db.models.base import Model
from django.db.models.expressions import Combinable
from django.db.models.fields.related_descriptors import ManyToManyDescriptor
from django.db.models.manager import EmptyManager
from django.utils.functional import _StrOrPromise
from typing_extensions import Self, TypeAlias
Expand All @@ -20,22 +22,68 @@ class PermissionManager(models.Manager[Permission]):
def get_by_natural_key(self, codename: str, app_label: str, model: str) -> Permission: ...

class Permission(models.Model):
content_type_id: int
objects: ClassVar[PermissionManager]

id: models.AutoField
pk: models.AutoField
name = models.CharField(max_length=255)
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
content_type = models.ForeignKey[ContentType | Combinable, ContentType](ContentType, on_delete=models.CASCADE)
content_type_id: int
codename = models.CharField(max_length=100)
group_set: ManyToManyDescriptor[Group, _Group_permissions]
user_set: ManyToManyDescriptor[User, _User_permissions]
def natural_key(self) -> tuple[str, str, str]: ...

class GroupManager(models.Manager[Group]):
def get_by_natural_key(self, name: str) -> Group: ...

# This is a model that only exists in Django's model registry and doesn't have any
# class statement form. It's the through model between 'Group' and 'Permission'.
@type_check_only
class _Group_permissions(models.Model):
objects: ClassVar[models.Manager[Self]]

id: models.AutoField
pk: models.AutoField
group: models.ForeignKey[Group | Combinable, Group]
group_id: int
permission: models.ForeignKey[Permission | Combinable, Permission]
permission_id: int

# This is a model that only exists in Django's model registry and doesn't have any
# class statement form. It's the through model between 'User' and 'Group'.
@type_check_only
class _User_groups(models.Model):
objects: ClassVar[models.Manager[Self]]

id: models.AutoField
pk: models.AutoField
user: models.ForeignKey[User | Combinable, User]
user_id: int
group: models.ForeignKey[Group | Combinable, Group]
group_id: int

# This is a model that only exists in Django's model registry and doesn't have any
# class statement form. It's the through model between 'User' and 'Permission'.
@type_check_only
class _User_permissions(models.Model):
objects: ClassVar[models.Manager[Self]]

id: models.AutoField
pk: models.AutoField
user: models.ForeignKey[User | Combinable, User]
user_id: int
permission: models.ForeignKey[Permission | Combinable, Permission]
permission_id: int

class Group(models.Model):
objects: ClassVar[GroupManager]

id: models.AutoField
pk: models.AutoField
name = models.CharField(max_length=150)
permissions = models.ManyToManyField(Permission)
permissions = models.ManyToManyField[Permission, _Group_permissions](Permission)
user_set: ManyToManyDescriptor[User, _User_groups]
def natural_key(self) -> tuple[str]: ...

_T = TypeVar("_T", bound=Model)
Expand All @@ -58,8 +106,8 @@ class UserManager(BaseUserManager[_T]):

class PermissionsMixin(models.Model):
is_superuser = models.BooleanField()
groups = models.ManyToManyField(Group)
user_permissions = models.ManyToManyField(Permission)
groups = models.ManyToManyField[Group, _User_groups](Group)
user_permissions = models.ManyToManyField[Permission, _User_permissions](Permission)

def get_user_permissions(self, obj: _AnyUser | None = ...) -> set[str]: ...
def get_group_permissions(self, obj: _AnyUser | None = ...) -> set[str]: ...
Expand Down Expand Up @@ -90,7 +138,9 @@ class AbstractUser(AbstractBaseUser, PermissionsMixin):
self, subject: _StrOrPromise, message: _StrOrPromise, from_email: str = ..., **kwargs: Any
) -> None: ...

class User(AbstractUser): ...
class User(AbstractUser):
id: models.AutoField
pk: models.AutoField

class AnonymousUser:
id: None
Expand Down
10 changes: 8 additions & 2 deletions django-stubs/contrib/contenttypes/models.pyi
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
from typing import Any, ClassVar

from django.contrib.admin.models import LogEntry
from django.contrib.auth.models import Permission
from django.db import models
from django.db.models.base import Model
from django.db.models.fields.related_descriptors import ReverseManyToOneDescriptor
from django.db.models.query import QuerySet

class ContentTypeManager(models.Manager[ContentType]):
Expand All @@ -12,13 +15,16 @@ class ContentTypeManager(models.Manager[ContentType]):
def clear_cache(self) -> None: ...

class ContentType(models.Model):
id: int
id: models.AutoField
pk: models.AutoField
app_label = models.CharField(max_length=100)
model = models.CharField(max_length=100)
logentry_set: ReverseManyToOneDescriptor[LogEntry]
permission_set: ReverseManyToOneDescriptor[Permission]
objects: ClassVar[ContentTypeManager]
@property
def name(self) -> str: ...
def model_class(self) -> type[Model] | None: ...
def get_object_for_this_type(self, **kwargs: Any) -> Model: ...
def get_all_objects_for_this_type(self, **kwargs: Any) -> QuerySet: ...
def get_all_objects_for_this_type(self, **kwargs: Any) -> QuerySet[Model]: ...
def natural_key(self) -> tuple[str, str]: ...
21 changes: 20 additions & 1 deletion django-stubs/contrib/flatpages/models.pyi
Original file line number Diff line number Diff line change
@@ -1,12 +1,31 @@
from typing import ClassVar, type_check_only

from django.contrib.sites.models import Site
from django.db import models
from django.db.models.expressions import Combinable
from typing_extensions import Self

# This is a model that only exists in Django's model registry and doesn't have any
# class statement form. It's the through model between 'FlatPage' and 'Site'.
@type_check_only
class _FlatPage_sites(models.Model):
objects: ClassVar[models.Manager[Self]]

id: models.AutoField
pk: models.AutoField
site: models.ForeignKey[Site | Combinable, Site]
site_id: int
flatpage: models.ForeignKey[FlatPage | Combinable, FlatPage]
flatpage_id: int

class FlatPage(models.Model):
id: models.AutoField
pk: models.AutoField
url: models.CharField
title: models.CharField
content: models.TextField
enable_comments: models.BooleanField
template_name: models.CharField
registration_required: models.BooleanField
sites: models.ManyToManyField[Site, Site]
sites: models.ManyToManyField[Site, _FlatPage_sites]
def get_absolute_url(self) -> str: ...
Loading
Loading