Add stubs for django-import-export (#11709)

This commit is contained in:
Victorien
2024-12-28 16:56:31 +01:00
committed by GitHub
parent ff4237fa24
commit eb8af63e70
19 changed files with 766 additions and 0 deletions

View File

@@ -44,6 +44,7 @@
"stubs/corus",
"stubs/dateparser",
"stubs/defusedxml",
"stubs/django-import-export",
"stubs/docker",
"stubs/docutils",
"stubs/Flask-SocketIO",

View File

@@ -0,0 +1,6 @@
version = "3.3.*"
upstream_repository = "https://github.com/django-import-export/django-import-export"
requires = ["django-stubs"] # Add tablib when typed, and update _Incomplete aliases in stubs
[tool.stubtest]
skip = true # Django requires configured settings at runtime

View File

@@ -0,0 +1 @@
__version__: str

View File

@@ -0,0 +1,114 @@
from _typeshed import Incomplete
from collections.abc import Callable
from logging import Logger
from typing import Any, TypeVar
from typing_extensions import TypeAlias, deprecated
from django.contrib import admin
from django.contrib.admin.helpers import ActionForm
from django.core.files import File
from django.db.models import Model, QuerySet
from django.forms import Form, Media
from django.http.request import HttpRequest
from django.http.response import HttpResponse
from django.template.response import TemplateResponse
from django.urls import URLPattern
from .formats.base_formats import Format
from .mixins import BaseExportMixin, BaseImportMixin
from .results import Result
from .tmp_storages import BaseStorage
Dataset: TypeAlias = Incomplete # tablib.Dataset
logger: Logger
_ModelT = TypeVar("_ModelT", bound=Model)
class ImportExportMixinBase:
base_change_list_template: str
change_list_template: str
def __init__(self, *args: Any, **kwargs: Any) -> None: ...
def init_change_list_template(self) -> None: ...
def get_model_info(self) -> tuple[str, str]: ...
def changelist_view(self, request: HttpRequest, extra_context: dict[str, Any] | None = None) -> HttpResponse: ...
class ImportMixin(BaseImportMixin[_ModelT], ImportExportMixinBase):
import_export_change_list_template: str
import_template_name: str
import_form_class: type[Form] = ...
confirm_form_class: type[Form] = ...
from_encoding: str
skip_admin_log: bool | None
tmp_storage_class: str | type[BaseStorage]
def get_skip_admin_log(self) -> bool: ...
def get_tmp_storage_class(self) -> type[BaseStorage]: ...
def has_import_permission(self, request: HttpRequest) -> bool: ...
def get_urls(self) -> list[URLPattern]: ...
def process_import(self, request: HttpRequest, *args: Any, **kwargs: Any) -> HttpResponse: ...
def process_dataset(
self,
dataset: Dataset,
confirm_form: Form,
request: HttpRequest,
*args: Any,
rollback_on_validation_errors: bool = False,
**kwargs: Any,
) -> Result: ...
def process_result(self, result: Result, request: HttpRequest) -> HttpResponse: ...
def generate_log_entries(self, result: Result, request: HttpRequest) -> None: ...
def add_success_message(self, result: Result, request: HttpRequest) -> None: ...
def get_import_context_data(self, **kwargs: Any) -> dict[str, Any]: ...
def get_context_data(self, **kwargs: Any) -> dict[str, Any]: ...
@deprecated("Use get_import_form_class instead")
def get_import_form(self) -> type[Form]: ...
@deprecated("Use get_confirm_form_class instead")
def get_confirm_import_form(self) -> type[Form]: ...
@deprecated("Use get_import_form_kwargs or get_confirm_form_kwargs")
def get_form_kwargs(self, form: Form, *args: Any, **kwargs: Any) -> dict[str, Any]: ...
def create_import_form(self, request: HttpRequest) -> Form: ...
def get_import_form_class(self, request: HttpRequest) -> type[Form]: ...
def get_import_form_kwargs(self, request: HttpRequest) -> dict[str, Any]: ...
def get_import_form_initial(self, request: HttpRequest) -> dict[str, Any]: ...
def create_confirm_form(self, request: HttpRequest, import_form: Form | None = None) -> Form: ...
def get_confirm_form_class(self, request: HttpRequest) -> type[Form]: ...
def get_confirm_form_kwargs(self, request: HttpRequest, import_form: Form | None = None) -> dict[str, Any]: ...
def get_confirm_form_initial(self, request: HttpRequest, import_form: Form | None) -> dict[str, Any]: ...
def get_import_data_kwargs(self, request: HttpRequest, *args: Any, **kwargs: Any) -> dict[str, Any]: ...
def write_to_tmp_storage(self, import_file: File[bytes], input_format: Format) -> BaseStorage: ...
def add_data_read_fail_error_to_form(self, form: Form, e: Exception) -> None: ...
def import_action(self, request: HttpRequest, *args: Any, **kwargs: Any) -> TemplateResponse: ...
def changelist_view(self, request: HttpRequest, extra_context: dict[str, Any] | None = None) -> HttpResponse: ...
class ExportMixin(BaseExportMixin[_ModelT], ImportExportMixinBase):
import_export_change_list_template: str | None
export_template_name: str
to_encoding: str | None
export_form_class: type[Form] = ...
def get_urls(self) -> list[URLPattern]: ...
def has_export_permission(self, request: HttpRequest) -> bool: ...
def get_export_queryset(self, request: HttpRequest) -> QuerySet[_ModelT]: ...
def get_export_data(self, file_format: Format, queryset: QuerySet[_ModelT], *args: Any, **kwargs: Any) -> str | bytes: ...
def get_export_context_data(self, **kwargs: Any) -> dict[str, Any]: ...
def get_context_data(self, **kwargs: Any) -> dict[str, Any]: ...
@deprecated("Use get_export_form_class or use the export_form_class attribute")
def get_export_form(self) -> Form: ...
def get_export_form_class(self) -> type[Form]: ...
def export_action(self, request: HttpRequest, *args: Any, **kwargs: Any) -> TemplateResponse: ...
def changelist_view(self, request: HttpRequest, extra_context: dict[str, Any] | None = None) -> HttpResponse: ...
def get_export_filename(self, request: HttpRequest, queryset: QuerySet[_ModelT], file_format: Format) -> str: ... # type: ignore[override]
class ImportExportMixin(ImportMixin[_ModelT], ExportMixin[_ModelT]):
import_export_change_list_template: str
class ImportExportModelAdmin(ImportExportMixin[_ModelT], admin.ModelAdmin[_ModelT]): ... # type: ignore[misc]
class ExportActionMixin(ExportMixin[_ModelT]):
action_form: type[ActionForm]
def __init__(self, *args: Any, **kwargs: Any) -> None: ...
def export_admin_action(self, request: HttpRequest, queryset: QuerySet[_ModelT]): ...
def get_actions(self, request: HttpRequest) -> dict[str, tuple[Callable[..., str], str, str] | None]: ...
@property
def media(self) -> Media: ...
class ExportActionModelAdmin(ExportActionMixin[_ModelT], admin.ModelAdmin[_ModelT]): ... # type: ignore[misc]
class ImportExportActionModelAdmin(ImportMixin[_ModelT], ExportActionModelAdmin[_ModelT]): ... # type: ignore[misc]

View File

@@ -0,0 +1,2 @@
class ImportExportError(Exception): ...
class FieldError(ImportExportError): ...

View File

@@ -0,0 +1,34 @@
from collections.abc import Callable, Mapping
from typing import Any, ClassVar
from django.db.models import Model
from django.db.models.fields import NOT_PROVIDED
from .widgets import Widget
class Field:
empty_values: ClassVar[list[str | None]]
attribute: str | None
default: type[NOT_PROVIDED] | Callable[[], Any] | Any
column_name: str | None
widget: Widget
readonly: bool
saves_null_values: bool
dehydrate_method: str
m2m_add: bool
def __init__(
self,
attribute: str | None = None,
column_name: str | None = None,
widget: Widget | None = None,
default: type[NOT_PROVIDED] | Callable[[], Any] | Any = ...,
readonly: bool = False,
saves_null_values: bool = True,
dehydrate_method: str | None = None,
m2m_add: bool = False,
) -> None: ...
def clean(self, data: Mapping[str, Any], **kwargs: Any) -> Any: ...
def get_value(self, obj: Model) -> Any: ...
def save(self, obj: Model, data: Mapping[str, Any], is_m2m: bool = False, **kwargs: Any) -> None: ...
def export(self, obj: Model) -> str: ...
def get_dehydrate_method(self, field_name: str | None = None) -> str: ...

View File

@@ -0,0 +1,57 @@
from _typeshed import Incomplete, ReadableBuffer
from typing import IO, Any, ClassVar
from typing_extensions import Self, TypeAlias
Dataset: TypeAlias = Incomplete # tablib.Dataset
class Format:
def get_title(self) -> type[Self]: ...
def create_dataset(self, in_stream: str | bytes | IO[Any]) -> Dataset: ...
def export_data(self, dataset: Dataset, **kwargs: Any) -> Any: ...
def is_binary(self) -> bool: ...
def get_read_mode(self) -> str: ...
def get_extension(self) -> str: ...
def get_content_type(self) -> str: ...
@classmethod
def is_available(cls) -> bool: ...
def can_import(self) -> bool: ...
def can_export(self) -> bool: ...
class TablibFormat(Format):
TABLIB_MODULE: ClassVar[str]
CONTENT_TYPE: ClassVar[str]
encoding: str | None
def __init__(self, encoding: str | None = None) -> None: ...
def get_format(self) -> type[Any]: ...
def get_title(self) -> str: ... # type: ignore[override]
def create_dataset(self, in_stream: str | bytes | IO[Any], **kwargs: Any) -> Dataset: ... # type: ignore[override]
class TextFormat(TablibFormat): ...
class CSV(TextFormat):
def export_data(self, dataset: Dataset, **kwargs: Any) -> str: ...
class JSON(TextFormat):
def export_data(self, dataset: Dataset, **kwargs: Any) -> str: ...
class YAML(TextFormat):
def export_data(self, dataset: Dataset, **kwargs: Any) -> str: ...
class TSV(TextFormat):
def export_data(self, dataset: Dataset, **kwargs: Any) -> str: ...
class ODS(TextFormat):
def export_data(self, dataset: Dataset, **kwargs: Any) -> bytes: ...
class HTML(TextFormat):
def export_data(self, dataset: Dataset, **kwargs: Any) -> str: ...
class XLS(TablibFormat):
def export_data(self, dataset: Dataset, **kwargs: Any) -> bytes: ...
def create_dataset(self, in_stream: bytes) -> Dataset: ... # type: ignore[override]
class XLSX(TablibFormat):
def export_data(self, dataset: Dataset, **kwargs: Any) -> bytes: ...
def create_dataset(self, in_stream: ReadableBuffer) -> Dataset: ... # type: ignore[override]
DEFAULT_FORMATS: list[type[Format]]

View File

@@ -0,0 +1,31 @@
from typing import Any
from django import forms
from django.contrib.admin.helpers import ActionForm
from .formats.base_formats import Format
from .resources import Resource
class ImportExportFormBase(forms.Form):
resource: forms.ChoiceField
def __init__(self, *args: Any, resources: list[type[Resource[Any]]] | None = None, **kwargs: Any) -> None: ...
class ImportForm(ImportExportFormBase):
import_file: forms.FileField
input_format: forms.ChoiceField
def __init__(self, import_formats: list[Format], *args: Any, **kwargs: Any) -> None: ...
@property
def media(self) -> forms.Media: ...
class ConfirmImportForm(forms.Form):
import_file_name: forms.CharField
original_file_name: forms.CharField
input_format: forms.CharField
resource: forms.CharField
def clean_import_file_name(self) -> str: ...
class ExportForm(ImportExportFormBase):
file_format: forms.ChoiceField
def __init__(self, formats: list[Format], *args: Any, **kwargs: Any) -> None: ...
def export_action_form_factory(formats: list[tuple[str, str]]) -> type[ActionForm]: ...

View File

@@ -0,0 +1,23 @@
from _typeshed import Incomplete
from typing import Any
from typing_extensions import TypeAlias
from django.db.models import Model, QuerySet
from .fields import Field
from .resources import Resource
Dataset: TypeAlias = Incomplete # tablib.Dataset
class BaseInstanceLoader:
resource: Resource[Any]
dataset: Dataset | None
def __init__(self, resource: Resource[Any], dataset: Dataset | None = None) -> None: ...
def get_instance(self, row: dict[str, Any]) -> Model | None: ...
class ModelInstanceLoader(BaseInstanceLoader):
def get_queryset(self) -> QuerySet[Any]: ...
class CachedInstanceLoader(ModelInstanceLoader):
pk_field: Field
all_instances: dict[Any, Model]

View File

@@ -0,0 +1,66 @@
from _typeshed import Incomplete, SupportsGetItem
from logging import Logger
from typing import Any, Generic, TypeVar
from typing_extensions import TypeAlias
from django.db.models import Model, QuerySet
from django.forms import BaseForm, Form
from django.http.request import HttpRequest
from django.http.response import HttpResponse
from django.views.generic.edit import FormView
from .formats.base_formats import Format
from .resources import Resource
Dataset: TypeAlias = Incomplete # tablib.Dataset
logger: Logger
_ModelT = TypeVar("_ModelT", bound=Model)
class BaseImportExportMixin(Generic[_ModelT]):
resource_class: type[Resource[_ModelT]]
resource_classes: SupportsGetItem[int, type[Resource[_ModelT]]]
@property
def formats(self) -> list[type[Format]]: ...
@property
def export_formats(self) -> list[type[Format]]: ...
@property
def import_formats(self) -> list[type[Format]]: ...
def check_resource_classes(self, resource_classes: SupportsGetItem[int, type[Resource[_ModelT]]]) -> None: ...
def get_resource_classes(self) -> list[type[Resource[_ModelT]]]: ...
def get_resource_kwargs(self, request: HttpRequest, *args: Any, **kwargs: Any) -> dict[str, Any]: ...
def get_resource_index(self, form: Form) -> int: ...
class BaseImportMixin(BaseImportExportMixin[_ModelT]):
def get_import_resource_classes(self) -> list[type[Resource[_ModelT]]]: ...
def get_import_formats(self) -> list[Format]: ...
def get_import_resource_kwargs(self, request: HttpRequest, *args: Any, **kwargs: Any) -> dict[str, Any]: ...
def choose_import_resource_class(self, form: Form) -> type[Resource[_ModelT]]: ...
class BaseExportMixin(BaseImportExportMixin[_ModelT]):
model: Model
escape_exported_data: bool
escape_html: bool
escape_formulae: bool
@property
def should_escape_html(self) -> bool: ...
@property
def should_escape_formulae(self) -> bool: ...
def get_export_formats(self) -> list[Format]: ...
def get_export_resource_classes(self) -> list[Resource[_ModelT]]: ...
def choose_export_resource_class(self, form: Form) -> Resource[_ModelT]: ...
def get_export_resource_kwargs(self, request: HttpRequest, *args: Any, **kwargs: Any) -> dict[str, Any]: ...
def get_data_for_export(self, request: HttpRequest, queryset: QuerySet[_ModelT], *args: Any, **kwargs: Any) -> Dataset: ...
def get_export_filename(self, file_format: Format) -> str: ...
class ExportViewMixin(BaseExportMixin[_ModelT]):
form_class: type[BaseForm] = ...
def get_export_data(self, file_format: Format, queryset: QuerySet[_ModelT], *args: Any, **kwargs: Any) -> str | bytes: ...
def get_context_data(self, **kwargs: Any) -> dict[str, Any]: ...
def get_form_kwargs(self) -> dict[str, Any]: ...
_FormT = TypeVar("_FormT", bound=BaseForm)
class ExportViewFormMixin(ExportViewMixin[_ModelT], FormView[_FormT]): # type: ignore[misc]
def form_valid(self, form: _FormT) -> HttpResponse: ...

View File

@@ -0,0 +1,232 @@
from _typeshed import Incomplete
from collections import OrderedDict
from collections.abc import Iterator, Sequence
from functools import partial
from logging import Logger
from typing import Any, ClassVar, Generic, Literal, NoReturn, TypeVar, overload
from typing_extensions import TypeAlias, deprecated
from django.db.models import Field as DjangoField, ForeignObjectRel, Model, QuerySet
from django.utils.safestring import SafeString
from .fields import Field
from .instance_loaders import BaseInstanceLoader
from .results import Error, Result, RowResult
from .widgets import ForeignKeyWidget, ManyToManyWidget, Widget
Dataset: TypeAlias = Incomplete # tablib.Dataset
logger: Logger
@overload
def get_related_model(field: ForeignObjectRel) -> Model: ...
@overload
def get_related_model(field: DjangoField[Any, Any]) -> Model | None: ...
def has_natural_foreign_key(model: Model) -> bool: ...
class ResourceOptions(Generic[_ModelT]):
model: _ModelT
fields: Sequence[str] | None
exclude: Sequence[str] | None
instance_loader_class: type[BaseInstanceLoader] | None
import_id_fields: Sequence[str]
export_order: Sequence[str] | None
widgets: dict[str, Any] | None
use_transactions: bool | None
skip_unchanged: bool
report_skipped: bool
clean_model_instances: bool
chunk_size: int | None
skip_diff: bool
skip_html_diff: bool
use_bulk: bool
batch_size: int
force_init_instance: bool
using_db: str | None
store_row_values: bool
store_instance: bool
use_natural_foreign_keys: bool
class DeclarativeMetaclass(type):
def __new__(cls, name: str, bases: tuple[type[Any], ...], attrs: dict[str, Any]): ...
class Diff:
left: list[str]
right: list[str]
new: bool
def __init__(self, resource: Resource[_ModelT], instance: _ModelT, new: bool) -> None: ...
def compare_with(self, resource: Resource[_ModelT], instance: _ModelT, dry_run: bool = False) -> None: ...
def as_html(self) -> list[SafeString]: ...
_ModelT = TypeVar("_ModelT", bound=Model)
class Resource(Generic[_ModelT], metaclass=DeclarativeMetaclass):
_meta: ResourceOptions[_ModelT]
fields: OrderedDict[str, Field]
create_instances: list[_ModelT]
update_instances: list[_ModelT]
delete_instances: list[_ModelT]
def __init__(self, **kwargs: Any) -> None: ...
@classmethod
def get_result_class(self) -> type[Result]: ...
@classmethod
def get_row_result_class(self) -> type[RowResult]: ...
@classmethod
def get_error_result_class(self) -> type[Error]: ...
@classmethod
def get_diff_class(self) -> type[Diff]: ...
@classmethod
def get_db_connection_name(self) -> str: ...
def get_use_transactions(self) -> bool: ...
def get_chunk_size(self) -> int: ...
def get_fields(self, **kwargs: Any) -> list[Field]: ...
def get_field_name(self, field: Field) -> str: ...
def init_instance(self, row: dict[str, Any] | None = None) -> _ModelT: ...
def get_instance(self, instance_loader: BaseInstanceLoader, row: dict[str, Any]) -> _ModelT | None: ...
def get_or_init_instance(self, instance_loader: BaseInstanceLoader, row: dict[str, Any]) -> tuple[_ModelT | None, bool]: ...
def get_import_id_fields(self) -> Sequence[str]: ...
def get_bulk_update_fields(self) -> list[str]: ...
def bulk_create(
self,
using_transactions: bool,
dry_run: bool,
raise_errors: bool,
batch_size: int | None = None,
result: Result | None = None,
) -> None: ...
def bulk_update(
self,
using_transactions: bool,
dry_run: bool,
raise_errors: bool,
batch_size: int | None = None,
result: Result | None = None,
) -> None: ...
def bulk_delete(self, using_transactions: bool, dry_run: bool, raise_errors: bool, result: Result | None = None) -> None: ...
def validate_instance(
self, instance: _ModelT, import_validation_errors: dict[str, Any] | None = None, validate_unique: bool = True
) -> None: ...
def save_instance(
self, instance: _ModelT, is_create: bool, using_transactions: bool = True, dry_run: bool = False
) -> None: ...
def before_save_instance(self, instance: _ModelT, using_transactions: bool, dry_run: bool) -> None: ...
def after_save_instance(self, instance: _ModelT, using_transactions: bool, dry_run: bool) -> None: ...
def delete_instance(self, instance: _ModelT, using_transactions: bool = True, dry_run: bool = False) -> None: ...
def before_delete_instance(self, instance: _ModelT, dry_run: bool) -> None: ...
def after_delete_instance(self, instance: _ModelT, dry_run: bool) -> None: ...
def import_field(self, field: Field, obj: _ModelT, data: dict[str, Any], is_m2m: bool = False, **kwargs: Any) -> None: ...
def get_import_fields(self) -> list[Field]: ...
def import_obj(self, obj: _ModelT, data: dict[str, Any], dry_run: bool, **kwargs: Any) -> None: ...
def save_m2m(self, obj: _ModelT, data: dict[str, Any], using_transactions: bool, dry_run: bool) -> None: ...
def for_delete(self, row: dict[str, Any], instance: _ModelT) -> bool: ...
def skip_row(
self, instance: _ModelT, original: _ModelT, row: dict[str, Any], import_validation_errors: dict[str, Any] | None = None
) -> bool: ...
def get_diff_headers(self) -> list[str]: ...
def before_import(self, dataset: Dataset, using_transactions: bool, dry_run: bool, **kwargs: Any) -> None: ...
def after_import(self, dataset: Dataset, result: Result, using_transactions: bool, dry_run: bool, **kwargs: Any) -> None: ...
def before_import_row(self, row: dict[str, Any], row_number: int | None = None, **kwargs: Any) -> None: ...
def after_import_row(
self, row: dict[str, Any], row_result: RowResult, row_number: int | None = None, **kwargs: Any
) -> None: ...
def after_import_instance(self, instance: _ModelT, new: bool, row_number: int | None = None, **kwargs: Any) -> None: ...
@overload
def handle_import_error(self, result: Result, error: Exception, raise_errors: Literal[True]) -> NoReturn: ...
@overload
def handle_import_error(self, result: Result, error: Exception, raise_errors: Literal[False] = ...) -> None: ...
@overload
@deprecated("raise_errors argument is deprecated and will be removed in a future release.")
def import_row(
self,
row: dict[str, Any],
instance_loader: BaseInstanceLoader,
using_transactions: bool = True,
dry_run: bool = False,
*,
raise_errors: bool,
**kwargs: Any,
) -> RowResult: ...
@overload
def import_row(
self,
row: dict[str, Any],
instance_loader: BaseInstanceLoader,
using_transactions: bool = True,
dry_run: bool = False,
raise_errors: None = None,
**kwargs: Any,
) -> RowResult: ...
def import_data(
self,
dataset: Dataset,
dry_run: bool = False,
raise_errors: bool = False,
use_transactions: bool | None = None,
collect_failed_rows: bool = False,
rollback_on_validation_errors: bool = False,
**kwargs: Any,
) -> Result: ...
@overload
@deprecated("rollback_on_validation_errors argument is deprecated and will be removed in a future release.")
def import_data_inner(
self,
dataset: Dataset,
dry_run: bool,
raise_errors: bool,
using_transactions: bool,
collect_failed_rows: bool,
rollback_on_validation_errors: bool,
**kwargs: Any,
) -> Result: ...
@overload
def import_data_inner(
self,
dataset: Dataset,
dry_run: bool,
raise_errors: bool,
using_transactions: bool,
collect_failed_rows: bool,
rollback_on_validation_errors: None = None,
**kwargs: Any,
) -> Result: ...
def get_export_order(self) -> tuple[str, ...]: ...
def before_export(self, queryset: QuerySet[_ModelT], *args: Any, **kwargs: Any) -> None: ...
def after_export(self, queryset: QuerySet[_ModelT], data: Dataset, *args: Any, **kwargs: Any) -> None: ...
def filter_export(self, queryset: QuerySet[_ModelT], *args: Any, **kwargs: Any) -> QuerySet[_ModelT]: ...
def export_field(self, field: Field, obj: _ModelT) -> str: ...
def get_export_fields(self) -> list[Field]: ...
def export_resource(self, obj: _ModelT) -> list[str]: ...
def get_export_headers(self) -> list[str]: ...
def get_user_visible_headers(self) -> list[str]: ...
def get_user_visible_fields(self) -> list[str]: ...
def iter_queryset(self, queryset: QuerySet[_ModelT]) -> Iterator[_ModelT]: ...
def export(self, *args: Any, queryset: QuerySet[_ModelT] | None = None, **kwargs: Any) -> Dataset: ...
class ModelDeclarativeMetaclass(DeclarativeMetaclass):
def __new__(cls, name: str, bases: tuple[type[Any], ...], attrs: dict[str, Any]): ...
class ModelResource(Resource[_ModelT], metaclass=ModelDeclarativeMetaclass):
DEFAULT_RESOURCE_FIELD: ClassVar[type[Field]] = ...
WIDGETS_MAP: ClassVar[dict[str, type[Widget]]]
@classmethod
def get_m2m_widget(cls, field: DjangoField[Any, Any]) -> partial[ManyToManyWidget]: ...
@classmethod
def get_fk_widget(cls, field: DjangoField[Any, Any]) -> partial[ForeignKeyWidget[Any]]: ...
@classmethod
def widget_from_django_field(cls, f: DjangoField[Any, Any], default: type[Widget] = ...): ...
@classmethod
def widget_kwargs_for_field(self, field_name: str) -> dict[str, Any]: ...
@classmethod
def field_from_django_field(cls, field_name: str, django_field: DjangoField[Any, Any], readonly: bool) -> Field: ...
def get_queryset(self) -> QuerySet[_ModelT]: ...
def init_instance(self, row: dict[str, Any] | None = None): ...
def after_import(self, dataset: Dataset, result: Result, using_transactions: bool, dry_run: bool, **kwargs: Any) -> None: ...
@classmethod
def get_display_name(cls) -> str: ...
_ResourceT = TypeVar("_ResourceT", bound=Resource[Any])
# HK Type Vars could help type the first overload:
@overload
def modelresource_factory(model: Model, resource_class: type[_ResourceT]) -> _ResourceT: ...
@overload
def modelresource_factory(model: _ModelT) -> ModelResource[_ModelT]: ...

View File

@@ -0,0 +1,73 @@
from _typeshed import Incomplete
from collections import OrderedDict
from collections.abc import Iterator
from typing import Any, ClassVar, Literal
from typing_extensions import TypeAlias
from django.core.exceptions import ValidationError
from django.db.models import Model
Dataset: TypeAlias = Incomplete # tablib.Dataset
class Error:
error: Exception
traceback: str
row: dict[str, Any]
def __init__(self, error: Exception, traceback: str | None = None, row: dict[str, Any] | None = None) -> None: ...
_ImportType: TypeAlias = Literal["update", "new", "delete", "skip", "error", "invalid"]
class RowResult:
IMPORT_TYPE_UPDATE: ClassVar[Literal["update"]]
IMPORT_TYPE_NEW: ClassVar[Literal["new"]]
IMPORT_TYPE_DELETE: ClassVar[Literal["delete"]]
IMPORT_TYPE_SKIP: ClassVar[Literal["skip"]]
IMPORT_TYPE_ERROR: ClassVar[Literal["error"]]
IMPORT_TYPE_INVALID: ClassVar[Literal["invalid"]]
valid_import_types: frozenset[_ImportType]
errors: list[Error]
validation_error: ValidationError | None
diff: list[str] | None
import_type: _ImportType
row_values: dict[str, Any]
object_id: Any | None
object_repr: str | None
instance: Model
original: Model
new_record: bool | None
def __init__(self) -> None: ...
def add_instance_info(self, instance: Model) -> None: ...
class InvalidRow:
number: int
error: ValidationError
values: tuple[Any, ...]
error_dict: dict[str, list[str]]
def __init__(self, number: int, validation_error: ValidationError, values: tuple[Any, ...]) -> None: ...
@property
def field_specific_errors(self) -> dict[str, list[str]]: ...
@property
def non_field_specific_errors(self) -> list[str]: ...
@property
def error_count(self) -> int: ...
class Result:
base_errors: list[Error]
diff_headers: list[str]
rows: list[RowResult]
invalid_rows: list[InvalidRow]
failed_dataset: Dataset
totals: OrderedDict[_ImportType, int]
total_rows: int
def __init__(self) -> None: ...
def valid_rows(self) -> list[RowResult]: ...
def append_row_result(self, row_result: RowResult) -> None: ...
def append_base_error(self, error: Error) -> None: ...
def add_dataset_headers(self, headers: list[str] | None) -> None: ...
def append_failed_row(self, row: dict[str, Any], error) -> None: ...
def append_invalid_row(self, number: int, row: dict[str, Any], validation_error: ValidationError) -> None: ...
def increment_row_result_total(self, row_result: RowResult) -> None: ...
def row_errors(self) -> list[tuple[int, Any]]: ...
def has_errors(self) -> bool: ...
def has_validation_errors(self) -> bool: ...
def __iter__(self) -> Iterator[RowResult]: ...

View File

@@ -0,0 +1,4 @@
from django.dispatch import Signal
post_export: Signal
post_import: Signal

View File

@@ -0,0 +1,8 @@
from typing_extensions import LiteralString
from django.template import Library
register: Library
# @register.simple_tag # commented out for pytype
def compare_values(value1: str, value2: str) -> LiteralString: ...

View File

@@ -0,0 +1,30 @@
from typing import IO, Any, ClassVar
class BaseStorage:
name: str | None
read_mode: str
encoding: str | None
def __init__(self, *, name: str | None = None, read_mode: str = "", encoding: str | None = None) -> None: ...
def save(self, data: Any) -> None: ...
def read(self) -> None: ...
def remove(self) -> None: ...
class TempFolderStorage(BaseStorage):
def save(self, data: Any) -> None: ...
def read(self): ...
def remove(self) -> None: ...
def get_full_path(self) -> str: ...
class CacheStorage(BaseStorage):
CACHE_LIFETIME: int
CACHE_PREFIX: str
def save(self, data: Any) -> None: ...
def read(self): ...
def remove(self) -> None: ...
class MediaStorage(BaseStorage):
MEDIA_FOLDER: ClassVar[str]
def save(self, data: IO[Any]) -> None: ...
def read(self): ...
def remove(self) -> None: ...
def get_full_path(self) -> str: ...

View File

@@ -0,0 +1,18 @@
from collections.abc import Callable
from types import TracebackType
from typing import Any, TypeVar
from django.db.transaction import Atomic
_C = TypeVar("_C", bound=Callable[..., Any])
class atomic_if_using_transaction:
using_transactions: bool
context_manager: Atomic
def __init__(self, using_transactions: bool, using: str | None) -> None: ...
def __enter__(self) -> None: ...
def __exit__(
self, exc_type: type[BaseException] | None, exc_value: BaseException | None, exc_tb: TracebackType | None
) -> None: ...
def original(method: _C) -> _C: ...

View File

@@ -0,0 +1,66 @@
from collections.abc import Mapping
from datetime import datetime
from typing import Any, ClassVar, Generic, TypeVar
from django.db.models import Model, QuerySet
def format_datetime(value: datetime, datetime_format: str) -> str: ...
class Widget:
def clean(self, value: Any, row: Mapping[str, Any] | None = None, **kwargs: Any) -> Any: ...
def render(self, value: Any, obj: Model | None = None) -> Any: ...
class NumberWidget(Widget):
coerce_to_string: bool
def __init__(self, coerce_to_string: bool = False) -> None: ...
def is_empty(self, value: Any) -> bool: ...
def render(self, value: Any, obj: Model | None = None) -> Any: ...
class FloatWidget(NumberWidget): ...
class IntegerWidget(NumberWidget): ...
class DecimalWidget(NumberWidget): ...
class CharWidget(Widget):
coerce_to_string: bool
allow_blank: bool
def __init__(self, coerce_to_string: bool = False, allow_blank: bool = False) -> None: ...
class BooleanWidget(Widget):
TRUE_VALUES: ClassVar[list[str | int | bool]]
FALSE_VALUES: ClassVar[list[str | int | bool]]
NULL_VALUES: ClassVar[list[str | None]]
class DateWidget(Widget):
formats: tuple[str, ...]
def __init__(self, format: str | None = None) -> None: ...
class DateTimeWidget(Widget):
formats: tuple[str, ...]
def __init__(self, format: str | None = None) -> None: ...
class TimeWidget(Widget):
formats: tuple[str, ...]
def __init__(self, format: str | None = None) -> None: ...
class DurationWidget(Widget): ...
class SimpleArrayWidget(Widget):
separator: str
def __init__(self, separator: str | None = None) -> None: ...
class JSONWidget(Widget): ...
_ModelT = TypeVar("_ModelT", bound=Model)
class ForeignKeyWidget(Widget, Generic[_ModelT]):
model: _ModelT
field: str
use_natural_foreign_keys: bool
def __init__(self, model: _ModelT, field: str = "pk", use_natural_foreign_keys: bool = False, **kwargs: Any) -> None: ...
def get_queryset(self, value: Any, row: Mapping[str, Any], *args: Any, **kwargs: Any) -> QuerySet[_ModelT]: ...
class ManyToManyWidget(Widget):
model: Model
separator: str
field: str
def __init__(self, model, separator: str | None = None, field: str | None = None, **kwargs: Any) -> None: ...