docs(README): Fix indentation in list and examples (#1083)

Run examples through black for uniformity, link `HttpModel`
This commit is contained in:
Tony Narlock
2022-08-01 18:39:14 -05:00
committed by GitHub
parent 966472994b
commit 5334a80c9b

View File

@@ -100,37 +100,40 @@ This happens because these Django classes do not support [`__class_getitem__`](h
1. You can go with our [`django_stubs_ext`](https://github.com/typeddjango/django-stubs/tree/master/django_stubs_ext) helper, that patches all the types we use as Generic in django. 1. You can go with our [`django_stubs_ext`](https://github.com/typeddjango/django-stubs/tree/master/django_stubs_ext) helper, that patches all the types we use as Generic in django.
Install it: Install it:
```bash ```bash
pip install django-stubs-ext # as a production dependency pip install django-stubs-ext # as a production dependency
``` ```
And then place in your top-level settings: And then place in your top-level settings:
```python ```python
import django_stubs_ext import django_stubs_ext
django_stubs_ext.monkeypatch() django_stubs_ext.monkeypatch()
``` ```
Note: This monkey patching approach will only work when using Python 3.7 and higher, when the `__class_getitem__` magic method was introduced. Note: This monkey patching approach will only work when using Python 3.7 and higher, when the `__class_getitem__` magic method was introduced.
2. You can use strings instead: `'QuerySet[MyModel]'` and `'Manager[MyModel]'`, this way it will work as a type for `mypy` and as a regular `str` in runtime. 2. You can use strings instead: `'QuerySet[MyModel]'` and `'Manager[MyModel]'`, this way it will work as a type for `mypy` and as a regular `str` in runtime.
### How can I create a HttpRequest that's guaranteed to have an authenticated user? ### How can I create a HttpRequest that's guaranteed to have an authenticated user?
Django's built in `HttpRequest` has the attribute `user` that resolves to the type Django's built in [`HttpRequest`](https://docs.djangoproject.com/en/4.0/ref/request-response/#django.http.HttpRequest) has the attribute `user` that resolves to the type
```python ```python
Union[User, AnonymousUser] Union[User, AnonymousUser]
``` ```
where `User` is the user model specified by the `AUTH_USER_MODEL` setting. where `User` is the user model specified by the `AUTH_USER_MODEL` setting.
If you want a `HttpRequest` that you can type-annotate with where you know that the user is authenticated you can subclass the normal `HttpRequest` class like so: If you want a `HttpRequest` that you can type-annotate with where you know that the user is authenticated you can subclass the normal `HttpRequest` class like so:
```python ```python
from django.http import HttpRequest from django.http import HttpRequest
from my_user_app.models import MyUser from my_user_app.models import MyUser
class AuthenticatedHttpRequest(HttpRequest): class AuthenticatedHttpRequest(HttpRequest):
user: MyUser user: MyUser
``` ```
@@ -150,15 +153,17 @@ Example:
from django.db import models from django.db import models
class MyModelQuerySet(models.QuerySet): class MyModelQuerySet(models.QuerySet):
pass pass
class MyModel(models.Model): class MyModel(models.Model):
bar = models.IntegerField() bar = models.IntegerField()
objects = MyModelQuerySet.as_manager() objects = MyModelQuerySet.as_manager()
def use_my_model(): def use_my_model():
foo = MyModel.objects.get(id=1) # This is `Any` but it should be `MyModel` foo = MyModel.objects.get(id=1) # This is `Any` but it should be `MyModel`
return foo.xyz # No error, but there should be return foo.xyz # No error, but there should be
``` ```
There is a workaround: use `Manager.from_queryset` instead. There is a workaround: use `Manager.from_queryset` instead.
@@ -168,18 +173,22 @@ Example:
```python ```python
from django.db import models from django.db import models
class MyModelQuerySet(models.QuerySet): class MyModelQuerySet(models.QuerySet):
pass pass
MyModelManager = models.Manager.from_queryset(MyModelQuerySet) MyModelManager = models.Manager.from_queryset(MyModelQuerySet)
class MyModel(models.Model): class MyModel(models.Model):
bar = models.IntegerField() bar = models.IntegerField()
objects = MyModelManager() objects = MyModelManager()
def use_my_model(): def use_my_model():
foo = MyModel.objects.get(id=1) foo = MyModel.objects.get(id=1)
return foo.xyz # Gives an error return foo.xyz # Gives an error
``` ```
### How do I annotate cases where I called QuerySet.annotate? ### How do I annotate cases where I called QuerySet.annotate?
@@ -203,23 +212,29 @@ from django_stubs_ext import WithAnnotations
from django.db import models from django.db import models
from django.db.models.expressions import Value from django.db.models.expressions import Value
class MyModel(models.Model): class MyModel(models.Model):
username = models.CharField(max_length=100) username = models.CharField(max_length=100)
def func(m: WithAnnotations[MyModel]) -> str: def func(m: WithAnnotations[MyModel]) -> str:
return m.asdf # OK, since the model is annotated as allowing any attribute return m.asdf # OK, since the model is annotated as allowing any attribute
func(MyModel.objects.annotate(foo=Value("")).get(id=1)) # OK func(MyModel.objects.annotate(foo=Value("")).get(id=1)) # OK
func(MyModel.objects.get(id=1)) # Error, since this model will not allow access to any attribute func(
MyModel.objects.get(id=1)
) # Error, since this model will not allow access to any attribute
class MyTypedDict(TypedDict): class MyTypedDict(TypedDict):
foo: str foo: str
def func2(m: WithAnnotations[MyModel, MyTypedDict]) -> str: def func2(m: WithAnnotations[MyModel, MyTypedDict]) -> str:
print(m.bar) # Error, since field "bar" is not in MyModel or MyTypedDict. print(m.bar) # Error, since field "bar" is not in MyModel or MyTypedDict.
return m.foo # OK, since we said field "foo" was allowed return m.foo # OK, since we said field "foo" was allowed
func(MyModel.objects.annotate(foo=Value("")).get(id=1)) # OK func(MyModel.objects.annotate(foo=Value("")).get(id=1)) # OK
func(MyModel.objects.annotate(bar=Value("")).get(id=1)) # Error func(MyModel.objects.annotate(bar=Value("")).get(id=1)) # Error