Django рдФрд░ DRF рдЯрд╛рдЗрдкрд┐рдВрдЧ

рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЬрд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рдореБрдЭреЗ рд╡реИрдХрд▓реНрдкрд┐рдХ рд╕реНрдерд┐рд░ рдЯрд╛рдЗрдкрд┐рдВрдЧ рдкрд╕рдВрдж рд╣реИред рдмрд╛рдд рдпрд╣ рд╣реИ рдХрд┐ рдХрднреА-рдХрднреА рдпрд╣ рд╡реИрдХрд▓реНрдкрд┐рдХ рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдЕрд╕рдВрднрд╡ рд╣реИред рдХреНрдпреЛрдВрдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдкрд╛рдпрдерди рдХреЗ рдЗрдХреЛрд╕рд┐рд╕реНрдЯрдо рдореЗрдВ рдмрд╣реБрдд рдмрдбрд╝реА рдЕрдирдХреИрдкреНрдб рдкрд░рд┐рдпреЛрдЬрдирд╛рдПрдВ рд╣реИрдВред


Django рдФрд░ Django-Rest-Framework рдЙрдирдореЗрдВ рд╕реЗ рджреЛ рдереЗред рдереЗред рдХреНрдпреЛрдВрдХрд┐ рдЕрдм рдЙрдиреНрд╣реЗрдВ рдЯрд╛рдЗрдк рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ! рдореБрдЭреЗ django рдФрд░ drf рд▓рд┐рдП рдЯрд╛рдЗрдк рдХрд┐рдП рдЧрдП Django рд╕рдВрдЧрдарди рдФрд░ рд╕реНрдЯрдмреНрд╕ рдХреА drf ред


рдпрд╣ рдПрдХ рд╕рдВрдХреНрд╖рд┐рдкреНрдд рдЯреНрдпреВрдЯреЛрд░рд┐рдпрд▓ рд╣реЛрдиреЗ рдЬрд╛ рд░рд╣рд╛ рд╣реИ рдФрд░ рдЧрд╛рдЗрдб рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░ рд░рд╣рд╛ рд╣реИред


рдпрд╢


рдореИрдВ рдЗрд╕ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЛ рдЖрдЧреЗ рдмрдврд╝рд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдФрд░ рдЗрд╕реЗ рд╕рдВрднрд╡ рдмрдирд╛рдиреЗ рд╡рд╛рд▓реЗ рд╕рднреА рдпреЛрдЧрджрд╛рдирдХрд░реНрддрд╛рдУрдВ рдХреЗ рд▓рд┐рдП @mkurnikov рдХреЛ рдПрдХ рдмрдбрд╝рд╛ "рдзрдиреНрдпрд╡рд╛рдж" рдХрд╣рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВред рддреБрдо рд╕рдм рдХрдорд╛рд▓ рд╣реЛ!


TLDR


рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ, рдореИрдВ рджрд┐рдЦрд╛ рд░рд╣рд╛ рд╣реВрдБ рдХрд┐ рдХреИрд╕реЗ django рдФрд░ drf рд╕рд╛рде рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВред рдЖрдк рдпрд╣рд╛рдБ рдкрд░рд┐рдгрд╛рдо рдкрд░ рдПрдХ рдирдЬрд╝рд░ рдбрд╛рд▓ рд╕рдХрддреЗ рд╣реИрдВред


рдФрд░ рдЖрдк рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХреА рдЧрдИ рд╕рднреА рдЪреАрдЬреЛрдВ рдХреЗ рд╕рд╛рде рдЕрдкрдиреА рдирдИ рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдХреЛ рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП wemake-django-template рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдпрд╣ рдмрд┐рд▓реНрдХреБрд▓ рдЙрджрд╛рд╣рд░рдг рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреА рддрд░рд╣ рджрд┐рдЦреЗрдЧрд╛ред


рд╢реБрд░реБрдЖрдд рд╣реЛ рд░рд╣реА рд╣реИ


рдЗрд╕ рдЫреЛрдЯреЗ рдЯреНрдпреВрдЯреЛрд░рд┐рдпрд▓ рдореЗрдВ, рдореИрдВ рдЖрдкрдХреЛ рдПрдХреНрд╢рди рдореЗрдВ django-stubs рдФрд░ djangorestframework-stubs рдХреА рдХрдИ рд╡рд┐рд╢реЗрд╖рддрд╛рдПрдВ djangorestframework-stubs ред рдореБрдЭреЗ рдЙрдореНрдореАрдж рд╣реИ рдХрд┐ рдпрд╣ рдЖрдкрдХреЛ рдпрдХреАрди рджрд┐рд▓рд╛рдПрдЧрд╛ рдХрд┐ рдЖрдкрдХреЗ рдЕрдЪреНрдЫреЗ рдХрд╛рдо рдХреЗ рдмрд╛рдж рдХрд┐рд╕реА рдХреЛ рдЪреАрдЬреЛрдВ рдХреЛ рджреЛрдЧреБрдирд╛ рдХрд░рдирд╛ рд╣реИред


рдЖрдк рд╣рдореЗрд╢рд╛ рдореВрд▓ рджрд╕реНрддрд╛рд╡реЗрдЬ рдХрд╛ рдЙрд▓реНрд▓реЗрдЦ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рд╕рднреА рдЪрд░рдгреЛрдВ рдХреЛ рднреА рдХрд╡рд░ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред


рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╣рдореЗрдВ рдПрдХ рдирдИ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдФрд░ рдПрдХ рд╕реНрд╡рдЪреНрдЫ рдЖрднрд╛рд╕реА рд╡рд╛рддрд╛рд╡рд░рдг рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА, рдЗрд╕рд▓рд┐рдП рд╣рдо рдЕрдкрдиреА рдирд┐рд░реНрднрд░рддрд╛рдПрдВ рд╕реНрдерд╛рдкрд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:


 pip install django django-stubs mypy 

рдлрд┐рд░ рд╣рдореЗрдВ рд╕рд╣реА рдврдВрдЧ рд╕реЗ mypy рдХреЛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреАред рдЗрд╕реЗ рджреЛ рдЪрд░рдгреЛрдВ рдореЗрдВ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╣рдо mypy рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░рддреЗ рд╣реИрдВ:


 # setup.cfg [mypy] # The mypy configurations: https://mypy.readthedocs.io/en/latest/config_file.html python_version = 3.7 check_untyped_defs = True disallow_any_generics = True disallow_untyped_calls = True disallow_untyped_decorators = True ignore_errors = False ignore_missing_imports = True implicit_reexport = False strict_optional = True strict_equality = True no_implicit_optional = True warn_unused_ignores = True warn_redundant_casts = True warn_unused_configs = True warn_unreachable = True warn_no_return = True 

рдлрд┐рд░ рд╣рдо django-stubs рдкреНрд▓рдЧрдЗрди рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░рддреЗ рд╣реИрдВ:


 # setup.cfg [mypy] # Appending to `mypy` section: plugins = mypy_django_plugin.main [mypy.plugins.django-stubs] django_settings_module = server.settings 

рд╣рдо рдпрд╣рд╛рдБ рдХреНрдпрд╛ рдХрд░рддреЗ рд╣реИрдВ?


  1. рд╣рдо рдХреБрдЫ рдЬрдЯрд┐рд▓ mypy рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╕реНрдерд┐рддрд┐рдпреЛрдВ (рдЬреИрд╕реЗ рдореЙрдбрд▓, рдХреНрд╡реЗрд░реАрд╕реЗрдЯ, рд╕реЗрдЯрд┐рдВрдЧреНрд╕, рдЖрджрд┐) рдореЗрдВ рдЪреЗрдХрд░ рдЕрдиреБрдорд╛рди рдкреНрд░рдХрд╛рд░реЛрдВ рдХреА рд╕рд╣рд╛рдпрддрд╛ рдХреЗ рд▓рд┐рдП рдПрдХ рдХрд╕реНрдЯрдо mypy рдкреНрд▓рдЧрдЗрди рдЬреЛрдбрд╝рддреЗ рд╣реИрдВред
  2. рд╣рдо django-stubs рд▓рд┐рдП рдХрд╕реНрдЯрдо рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рднреА рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ рддрд╛рдХрд┐ рдЗрд╕реЗ рд╕реЗрдЯрд┐рдВрдЧреНрд╕ рдкрд░ рдЗрдВрдЧрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХреЗ, рд╣рдо Django рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред рдЗрд╕реЗ рдЖрдпрд╛рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреАред

рдЕрдВрддрд┐рдо рдкрд░рд┐рдгрд╛рдо рдпрд╣рд╛рдВ рдкрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ ред


рдЕрдм рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рд╕рдм рдХреБрдЫ рд╕реНрдерд╛рдкрд┐рдд рдФрд░ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рд╣реИред рдЪрд▓рд┐рдП рдЪреЗрдХ рдХрд░рддреЗ рд╣реИрдВ рдмрд╛рддреЗрдВ!


рдЯрдВрдХрдг рд╡рд┐рдЪрд╛рд░


рдЖрдЗрдП рдЯрд╛рдЗрдкрд┐рдВрдЧ рд╡рд┐рдЪрд╛рд░реЛрдВ рд╕реЗ рд╢реБрд░реВ рдХрд░реЗрдВ рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдЗрд╕ рдкреНрд▓рдЧрдЗрди рдХреЗ рд╕рд╛рде рд╕рдмрд╕реЗ рдЖрд╕рд╛рди рдХрд╛рдо рд╣реИред


рдпрд╣рд╛рдВ рд╣рдорд╛рд░рд╛ рд╕рд░рд▓ рдХрд╛рд░реНрдп-рдЖрдзрд╛рд░рд┐рдд рджреГрд╢реНрдп рд╣реИ:


 # server/apps/main/views.py from django.http import HttpRequest, HttpResponse from django.shortcuts import render def index(request: HttpRequest) -> HttpResponse: reveal_type(request.is_ajax) reveal_type(request.user) return render(request, 'main/index.html') 

рдЖрдЗрдП рджреЗрдЦреЗрдВ рдФрд░ рджреЗрдЦреЗрдВ рдХрд┐ рдпрд╣ рдХрд┐рд╕ рдкреНрд░рдХрд╛рд░ рдХрд╛ рд╣реИред рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рд╣рдореЗрдВ PYTHONPATH рдХреЛ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛ рд╕рдХрддреА рд╣реИ, рдЗрд╕рд▓рд┐рдП mypy рд╣рдорд╛рд░реА рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЛ рдЖрдпрд╛рдд рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдЧреА:


 ┬╗ PYTHONPATH="$PYTHONPATH:$PWD" mypy server server/apps/main/views.py:14: note: Revealed type is 'def () -> builtins.bool' server/apps/main/views.py:15: note: Revealed type is 'django.contrib.auth.models.User' 

рдЪрд▓реЛ рдХреБрдЫ рддреЛрдбрд╝рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рддреЗ рд╣реИрдВ:


 # server/apps/main/views.py def index(request: HttpRequest) -> HttpResponse: return render(request.META, 'main/index.html') 

рдирд╣реАрдВ, рд╡рд╣рд╛рдБ рдПрдХ рдЯрд╛рдЗрдкреЛ рдФрд░ mypy рдЗрд╕реЗ рдкрдХрдбрд╝ рд▓реЗрдВрдЧреЗ:


 ┬╗ PYTHONPATH="$PYTHONPATH:$PWD" mypy server server/apps/main/views.py:18: error: Argument 1 to "render" has incompatible type "Dict[str, Any]"; expected "HttpRequest" 

рдпрд╣ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ! рдареАрдХ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рдмрд╣реБрдд рд╕реАрдзреЗ рдЖрдЧреЗ рд╣реИред рдЖрдЗрдП рд╣рдорд╛рд░реЗ рдЙрджрд╛рд╣рд░рдг рдХреЛ рдереЛрдбрд╝рд╛ рдЬрдЯрд┐рд▓ рдХрд░реЗрдВ рдФрд░ рдпрд╣ рджрд┐рдЦрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рд╣рдо рдХреИрд╕реЗ рдореЙрдбрд▓ рдФрд░ рдХреНрд╡реЗрд░реА рдЯрд╛рдЗрдк рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдПрдХ рдХрд╕реНрдЯрдо рдореЙрдбрд▓ рдмрдирд╛рдПрдВред


рдЯрд╛рдЗрдкрдХрд╛рд╕реНрдЯрд┐рдВрдЧ рдореЙрдбрд▓ рдФрд░ рдХреНрд╡реЗрд░реАрд╕реЗрдЯ


Django рдХрд╛ ORM рдПрдХ рдХрд┐рд▓рд░-рдлреАрдЪрд░ рд╣реИред рдпрд╣ рдмрд╣реБрдд рд▓рдЪреАрд▓рд╛ рдФрд░ рдЧрддрд┐рд╢реАрд▓ рд╣реИред рдЗрд╕рдХрд╛ рдорддрд▓рдм рдпрд╣ рднреА рд╣реИ рдХрд┐ рдЯрд╛рдЗрдк рдХрд░рдирд╛ рдХрдард┐рди рд╣реИред рдЖрдЗрдП рджреЗрдЦреЗрдВ рдХреБрдЫ рд╡рд┐рд╢реЗрд╖рддрд╛рдПрдВ рдЬреЛ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА django-stubs рджреНрд╡рд╛рд░рд╛ рдХрд╡рд░ рдХреА рдЧрдИ рд╣реИрдВред


рд╣рдорд╛рд░реЗ рдореЙрдбрд▓ рдХреА рдкрд░рд┐рднрд╛рд╖рд╛:


 # server/apps/main/models.py from django.contrib.auth import get_user_model from django.db import models User = get_user_model() class BlogPost(models.Model): author = models.ForeignKey(User, on_delete=models.CASCADE) text = models.TextField() is_published = models.BooleanField(default=False) created_at = models.DateTimeField(auto_now_add=True) def __str__(self) -> str: reveal_type(self.id) # example reveal of all fields in a model reveal_type(self.author) reveal_type(self.text) reveal_type(self.is_published) reveal_type(self.created_at) return '<BlogPost {0}>'.format(self.id) 

рдФрд░ рдЗрд╕ рдореЙрдбрд▓ рдХрд╛ рд╣рд░ рдХреНрд╖реЗрддреНрд░ django-stubs рджреНрд╡рд╛рд░рд╛ рдХрд╡рд░ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдЖрдЗрдП рджреЗрдЦреЗрдВ рдХрд┐ рдХреМрди рд╕реЗ рдкреНрд░рдХрд╛рд░ рд╕рд╛рдордиреЗ рдЖрдП рд╣реИрдВ:


 ┬╗ PYTHONPATH="$PYTHONPATH:$PWD" mypy server server/apps/main/models.py:21: note: Revealed type is 'builtins.int*' server/apps/main/models.py:22: note: Revealed type is 'django.contrib.auth.models.User*' server/apps/main/models.py:23: note: Revealed type is 'builtins.str*' server/apps/main/models.py:24: note: Revealed type is 'builtins.bool*' server/apps/main/models.py:25: note: Revealed type is 'datetime.datetime*' 

рд╕рдм рдХреБрдЫ рдЕрдЪреНрдЫрд╛ рд▓рдЧ рд░рд╣рд╛ рд╣реИ! рдореЙрдбрд▓ рдХреНрд╖реЗрддреНрд░ рдХреЛ рд╕рд╣реА рдЙрджрд╛рд╣рд░рдг рдкреНрд░рдХрд╛рд░реЛрдВ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП django-stubs рдХрд╕реНрдЯрдо mypy рдкреНрд▓рдЧрдЗрди рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред рдЗрд╕рд▓рд┐рдП рд╕рднреА рдкреНрд░рдХрд╛рд░ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдкреНрд░рдХрдЯ рд╣реЛрддреЗ рд╣реИрдВред


django-stubs рдкреНрд▓рдЧрдЗрди рдХреА рджреВрд╕рд░реА рдмрдбрд╝реА рд╡рд┐рд╢реЗрд╖рддрд╛ рдпрд╣ рд╣реИ рдХрд┐ рд╣рдо QuerySet рдЯрд╛рдЗрдк рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:


 # server/apps/main/logic/repo.py from django.db.models.query import QuerySet from server.apps.main.models import BlogPost def published_posts() -> 'QuerySet[BlogPost]': # works fine! return BlogPost.objects.filter( is_published=True, ) 

рдФрд░ рдпрд╣рд╛рдВ рдмрддрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ рдХрд┐ рдЗрд╕реЗ рдХреИрд╕реЗ рдЬрд╛рдВрдЪрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:


 reveal_type(published_posts().first()) # => Union[server.apps.main.models.BlogPost*, None] 

рд╣рдо .values() рдФрд░ .values_list() рдХреЙрд▓ рдХреЗ рд╕рд╛рде .values() рдХреЛ рднреА рдПрдиреЛрдЯреЗрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдпрд╣ рдкреНрд▓рдЧрдЗрди рд╕реНрдорд╛рд░реНрдЯ рд╣реИ!


рдореИрдВ рдХрдИ рд╡рд░реНрд╖реЛрдВ рд╕реЗ QuerySet s рдХреА рд╡рд╛рдкрд╕реА рдХрд░рдиреЗ QuerySet рд╡рд┐рдзрд┐рдпрд╛рдБ QuerySet рддрд░реАрдХреЛрдВ рд╕реЗ рдЬреВрдЭ рд░рд╣рд╛ рд╣реВрдБред рдпрд╣ рд╕реБрд╡рд┐рдзрд╛ рдореЗрд░реЗ рд▓рд┐рдП рдПрдХ рдмрдбрд╝реА рд╕рдорд╕реНрдпрд╛ рдХрд╛ рд╣рд▓ рдХрд░рддреА рд╣реИ: рдХреЛрдИ рдЕрдзрд┐рдХ Iterable[BlogPost] рдпрд╛ List[User] ред рдореИрдВ рдЕрдм рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдкреНрд░рдХрд╛рд░реЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддрд╛ рд╣реВрдВред


рдЯрд╛рдЗрдкрд┐рдВрдЧ рдПрдкреАрдЖрдИ


рд▓реЗрдХрд┐рди, рд╡рд┐рдЪрд╛рд░, рдореЙрдбрд▓, рд░реВрдк, рдХрдорд╛рдВрдб, рдпреВрдЖрд░рдПрд▓ рдФрд░ рд╡реНрдпрд╡рд╕реНрдерд╛рдкрдХ рдЯрд╛рдЗрдк рдХрд░рдирд╛ рд╣рдо рд╕рдм рдХреЗ рдкрд╛рд╕ рдирд╣реАрдВ рд╣реИред рдЯрдВрдХрдЬрдбрдВрдЧреЛ рдореЗрдВ рднреА djangorestframework рдХреЗ рд▓рд┐рдП djangorestframework ред рдЖрдЗрдП рдЗрд╕реЗ рд╕реНрдерд╛рдкрд┐рдд рдФрд░ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░реЗрдВ:


 pip install djangorestframework djangorestframework-stubs 

рдФрд░ рд╣рдо рд╕реАрд░рд┐рдпрд▓ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд╢реБрд░реВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:


 # server/apps/main/serializers.py from rest_framework import serializers from server.apps.main.models import BlogPost, User class UserSerializer(serializers.ModelSerializer): class Meta: model = User fields = ['username', 'email'] class BlogPostSerializer(serializers.HyperlinkedModelSerializer): author = UserSerializer() class Meta: model = BlogPost fields = ['author', 'text', 'is_published', 'created_at'] 

рджреГрд╢реНрдп:


 # server/apps/main/views.py from rest_framework import viewsets from server.apps.main.serializers import BlogPostSerializer from server.apps.main.models import BlogPost class BlogPostViewset(viewsets.ModelViewSet): serializer_class = BlogPostSerializer queryset = BlogPost.objects.all() 

рдФрд░ рд░рд╛рдЙрдЯрд░:


 # server/apps/main/urls.py from django.urls import path, include from rest_framework import routers from server.apps.main.views import BlogPostViewset, index router = routers.DefaultRouter() router.register(r'posts', BlogPostViewset) urlpatterns = [ path('', include(router.urls)), # ... ] 

рдпрд╣ рднреА рдирд╣реАрдВ рджрд┐рдЦрддрд╛ рд╣реИ рдХрд┐ рдХреБрдЫ рдмрджрд▓ рдЧрдпрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЕрдВрджрд░ рд╕рдм рдХреБрдЫ рдЯрд╛рдЗрдк рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ: рд╕реЗрдЯрд┐рдВрдЧреНрд╕, рдзрд╛рд░рд╛рд╡рд╛рд╣рд┐рдХ, рджреГрд╢реНрдп рдФрд░ рд░рд╛рдЙрдЯрд░ред рдпрд╣ рдЖрдкрдХреЛ рд╡реГрджреНрдзрд┐рд╢реАрд▓ рд░реВрдк рд╕реЗ рдЯрд╛рдЗрдкрд┐рдВрдЧ рдЬреЛрдбрд╝рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдЧрд╛ рдЬрд╣рд╛рдВ рдЖрдкрдХреЛ рдЙрдирдХреА рд╕рдмрд╕реЗ рдЕрдзрд┐рдХ рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред


рдЖрдЗрдП queryset = BlogPost.objects.all() рдХреЛ рдмрджрд▓рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВ
рд╣рдорд╛рд░реЗ рд╡рд┐рдЪрд╛рд░ рдореЗрдВ queryset = [1, 2, 3] рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП queryset = [1, 2, 3] :


 ┬╗ PYTHONPATH="$PYTHONPATH:$PWD" mypy server server/apps/main/views.py:25: error: Incompatible types in assignment (expression has type "List[int]", base class "GenericAPIView" defined the type as "Optional[QuerySet[Any]]") 

рдирд╣реАрдВ, рдпрд╣ рдХрд╛рдо рдирд╣реАрдВ рдХрд░реЗрдЧрд╛! рдЕрдкрдирд╛ рдХреЛрдб рдареАрдХ рдХрд░реЗрдВ!


рдирд┐рд╖реНрдХрд░реНрд╖


рдлреНрд░реЗрдорд╡рд░реНрдХ рдЗрдВрдЯрд░рдлреЗрд╕ рдЯрд╛рдЗрдк рдХрд░рдирд╛ рдПрдХ рдХрдорд╛рд▓ рдХреА рдмрд╛рдд рд╣реИред рдЬрдм returns рдФрд░ mappers рдЬреИрд╕реЗ рдЙрдкрдХрд░рдгреЛрдВ рдХреЗ рд╕рд╛рде рд╕рдВрдпреБрдХреНрдд рд╣реЛрддрд╛ рд╣реИ, рддреЛ рдпрд╣ рдЯрд╛рдЗрдк-рдлреНрд░реЗрдорд╡рд░реНрдХ рдЗрдВрдЯрд░рдлреЗрд╕ рдореЗрдВ рд▓рд┐рдкрдЯреЗ рдЯрд╛рдЗрдк-рд╕реЗрдл рдФрд░ рдбрд┐рдХреНрд▓реЗрдХреНрдЯрд┐рд╡ рдмрд┐рдЬрдиреЗрд╕ рд▓реЙрдЬрд┐рдХ рдХреЛ рд▓рд┐рдЦрдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдЧрд╛ред рдФрд░ рдЗрди рджреЛрдиреЛрдВ рдХреЗ рдмреАрдЪ рдХреА рдкрд░рдд рдореЗрдВ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреЛ рдХрдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдПред


рд╡реИрдХрд▓реНрдкрд┐рдХ рдХреНрд░рдорд┐рдХ рд╕реНрдерд┐рд░ рдЯрд╛рдЗрдкрд┐рдВрдЧ рднреА рдЖрдкрдХреЛ рддреЗрдЬреА рд╕реЗ рд╢реБрд░реВ рдХрд░рдиреЗ рдФрд░ рдХреЗрд╡рд▓ рддрднреА рдЬреЛрдбрд╝рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддреА рд╣реИ рдЬрдм рдЖрдкрдХрд╛ рдПрдкреАрдЖрдИ рд╕реНрдерд┐рд░ рд╣реЛрддрд╛ рд╣реИ рдпрд╛ рдмрд╣реБрдд рд╢реБрд░реБрдЖрдд рд╕реЗ рдЯрд╛рдЗрдк-рд╕рдВрдЪрд╛рд▓рд┐рдд рд╡рд┐рдХрд╛рд╕ рдХреЗ рд╕рд╛рде рдЬрд╛рддрд╛ рд╣реИред


рд╣рд╛рд▓рд╛рдБрдХрд┐, django-stubs рдФрд░ djangorestframework-stubs рдирдИ рдкрд░рд┐рдпреЛрдЬрдирд╛рдПрдБ рд╣реИрдВред рдЕрднреА рднреА рдмрд╣реБрдд рд╕рд╛рд░реЗ рдХреАрдбрд╝реЗ, рдирд┐рдпреЛрдЬрд┐рдд рд╡рд┐рд╢реЗрд╖рддрд╛рдПрдВ, рд▓рд╛рдкрддрд╛ рдкреНрд░рдХрд╛рд░ рдХреЗ рдЪрд╢реНрдореЗ рд╣реИрдВред рд╣рдо рдкрд╛рдпрдерди рдореЗрдВ рдбреЗрд╡рд▓рдкрд░ рдЯреВрд▓рд┐рдВрдЧ рдХреЛ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рднрдпрд╛рдирдХ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдореБрджрд╛рдп рдХреЗ рд╣рд░ рдпреЛрдЧрджрд╛рди рдХрд╛ рд╕реНрд╡рд╛рдЧрдд рдХрд░рддреЗ рд╣реИрдВред


рдореВрд▓ рд░реВрдк рд╕реЗ рдореЗрд░реЗ рдмреНрд▓реЙрдЧ рдкрд░ рдкреНрд░рдХрд╛рд╢рд┐рддред

Source: https://habr.com/ru/post/hi465007/


All Articles