This Week in Changelogs: Django and faker
Tags: todayilearned, twic, django, faker
Published: 2023-02-18 11:02:14

### Django 4.1.6, 4.1.7

- 4.1.6: [release notes](https://docs.djangoproject.com/en/4.1/releases/4.1.6/), [blog post](https://www.djangoproject.com/weblog/2023/feb/01/security-releases/)
- 4.1.7: [release notes](https://docs.djangoproject.com/en/4.1/releases/4.1.7/), [blog post](https://www.djangoproject.com/weblog/2023/feb/14/security-releases/)

[<kbd>9d7bd5a</kbd>](https://github.com/django/django/commit/9d7bd5a56b1ce0576e8e07a8001373576d277942)
An interesting bug of parsing the [`Accept-Language`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Language) header. The format of the header value is complex, so there's a bunch of [regular expressions](https://github.com/django/django/commit/9d7bd5a56b1ce0576e8e07a8001373576d277942#diff-cc1f617ac65a58aec8f73b7a909c5bb48e0391543fe64c4f7ee22d4333a529efR40-R56) and `@functools.lru_cache(maxsize=1000)` for caching the result. However, you can pass a huge header multiple times, causing DoS, so they added two `if` statements:
- one that checks if the length is less than `ACCEPT_LANGUAGE_HEADER_MAX_LENGTH` 
- second - for checking the comma-separated strings. So they decided not to just raise an exception or truncate the string by `[:ACCEPT_LANGUAGE_HEADER_MAX_LENGTH]`, but truncate the value in a safe way, so it can be parsed in a meaningful result.
Good job!

[<kbd>26b7a25</kbd>](https://github.com/django/django/commit/26b7a25632e7fe0b897bc9b88b5c364a4b6398b6)
There was a [bug](https://code.djangoproject.com/ticket/34291) in generated SQL, caused by that `.desc()` in the model's `Meta.constraints`:

```python
constraints = [
    UniqueConstraint(
        Lower("name").desc(), name="unique_lower_name"
    )
]
```

which resulted in `<...> WHERE LOWER("myapp_foo"."name") DESC <...>` when checking the uniqueness. Apparently, Django can check the constraints itself, not delegating it to the underlying database.

Although the fix is trivial, the case is not, and it wasn't covered in the [initial implementation](https://github.com/django/django/commit/667105877e6723c6985399803a364848891513cc).

By the way, I like how they use [typographic double quotes](https://github.com/django/django/commit/26b7a25632e7fe0b897bc9b88b5c364a4b6398b6#diff-ea321d4c8efedd284e435745051f8d44b2a87e6b09788facd62d63b460432677R679):
```python
msg = "Constraint “name_lower_uniq_desc” is violated."
```

[<kbd>a637d0b</kbd>](https://github.com/django/django/commit/a637d0bd22665edfe7af40b4da3297462ec3c9cf) [<kbd>f3b6a4f</kbd>](https://github.com/django/django/commit/f3b6a4f1f3f9edbed805e62f070221a5eb163d1a) Those `black` updates are annoying, mainly because they make `git blame` misleading. However, there's a solution I didn't know about:
- `git blame --ignore-revs-file <file>` - [ignore commits](https://git-scm.com/docs/git-blame#Documentation/git-blame.txt---ignore-revs-fileltfilegt) listed in the `file`.
- `.git-blame-ignore-revs` file - [make GitHub](https://docs.github.com/en/repositories/working-with-files/using-files/viewing-a-file#ignore-commits-in-the-blame-view) ignore them as well.

[<kbd>590a92e</kbd>](https://github.com/django/django/commit/590a92e4562c8ebd3eb25dc1e878bd1e3eb758d4)
The [bug](https://code.djangoproject.com/ticket/34319) was caused by the [commit](https://github.com/django/django/commit/667105877e6723c6985399803a364848891513cc) which we've already seen. Now you can safely raise `ValidationError` without the `code`.

[<kbd>628b33a</kbd>](https://github.com/django/django/commit/628b33a854a9c68ec8a0c51f382f304a0044ec92)
One more DoS fix, now it's about number of opened files when you put too many of them in one multipart payload. The fix introduces `TooManyFilesSent` exception, which results in HTTP 400 (`DATA_UPLOAD_MAX_NUMBER_FILES = 100` by default).

I like [this fragment](https://github.com/django/django/commit/628b33a854a9c68ec8a0c51f382f304a0044ec92#diff-701db8db8b42a48d7e02b7055a96db867d02b6f511371314ef905d74114f54ffR125-R128):

```python
try:
    return self._parse()
except Exception:
    if hasattr(self, "_files"):
        for _, files in self._files.lists():
            for fileobj in files:
                fileobj.close()
    raise
```

Beware of freeing your resources, garbage collector can't help you all the time!

### faker 16.6.1..17.0.0

Their [CHANGELOG](https://github.com/joke2k/faker/blob/deda2d229dbf56fcaf4e8f5ea522ad82dc365551/CHANGELOG.md) is quite descriptive, so I'll just highlight something that I liked.

- `faker` can generate valid image URLs using specific websites (TIL), and one of them, [PlaceIMG](https://placeimg.com/), is [shutting down](https://github.com/joke2k/faker/issues/1788), and they removed it from the list. The announcement is included in all the generated images:

![PlaceIMG is shutting down](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nkde7nj78v2eu1lg5cjk.png)

- Biased booleans [introduced](https://github.com/joke2k/faker/pull/1793).
- [Added `emoji`](https://github.com/joke2k/faker/commit/a78228818bf7a312dd4488ff8de9ff587fe70cc7) provider 🎉 🥳
- [Added new `es_AR`](https://github.com/joke2k/faker/pull/1784/files) provider, but for some reason it's not in the reflected in the [CHANGELOG](https://github.com/joke2k/faker/blob/deda2d229dbf56fcaf4e8f5ea522ad82dc365551/CHANGELOG.md).
- [Black formatting](https://github.com/joke2k/faker/commit/dc48bb5eafbb1fb3f422b07e06eedc1c61a72153) - always beautiful.

In addition, it turned out that GitHub can put those linter errors from the actions right in the code. I don't know yet how to add this, but I definitely want it!

![Inline warnings in GitHub diff](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kjcqg1rianz3nouq85cf.png)