Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,12 @@ jobs:
with:
python-version: ${{ matrix.python-version }}
cache: pip
cache-dependency-path: 'requirements.txt'
cache-dependency-path: 'pyproject.toml'

- name: Install dependencies
run: |
python -m pip install --upgrade pip setuptools wheel
python -m pip install -r requirements.txt
python -m pip install .

- name: Run tests
run: |
Expand Down
33 changes: 10 additions & 23 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,43 +1,30 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.3.0
rev: v5.0.0
hooks:
- id: check-yaml
- id: end-of-file-fixer
- id: trailing-whitespace
- id: mixed-line-ending
- repo: https://github.com/pycqa/flake8
rev: 4.0.1
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.9.4
hooks:
- id: flake8
- id: ruff
args: [--fix]
- id: ruff-format
- repo: https://github.com/pycqa/doc8
rev: 0.11.2
rev: v1.1.2
hooks:
- id: doc8
- repo: https://github.com/asottile/pyupgrade
rev: v2.34.0
hooks:
- id: pyupgrade
args: [--py38-plus]
- repo: https://github.com/adamchainz/django-upgrade
rev: 1.7.0
rev: 1.22.2
hooks:
- id: django-upgrade
args: [--target-version, "3.2"]
- repo: https://github.com/pycqa/isort
rev: 5.10.1
hooks:
- id: isort
args: [--target-version, "5.0"]
- repo: https://github.com/pre-commit/pygrep-hooks
rev: v1.9.0
rev: v1.10.0
hooks:
- id: python-check-blanket-noqa
- id: python-check-mock-methods
- id: python-no-eval
- id: python-no-log-warn
- repo: https://github.com/psf/black
rev: 22.3.0
hooks:
- id: black
language_version: python3
entry: black --target-version=py38
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ warning. Do what's comfortable.

If not, I highly recommend using the Windows Subsystem for Linux
([docs](https://learn.microsoft.com/en-us/windows/wsl/about)). If you do, the
rest of the instructions will work for you. If you don't have access to that,
rest of the instructions will work for you. If you don't have access to that,
please scroll down to [Windows non-WSL Setup](#windows-non-wsl-setup).

---
Expand All @@ -95,7 +95,7 @@ please scroll down to [Windows non-WSL Setup](#windows-non-wsl-setup).
```
3. Install the project dependencies.
```shell
pip install -r requirements.txt
pip install -e .
```
4. Create a new .env file.
```shell
Expand Down Expand Up @@ -151,7 +151,7 @@ Proceed to [Lab 1](docs/lab1.md).
```
3. Install the project dependencies.
```shell
pip install -r requirements.txt
pip install -e .
```
4. Create a new .env file.
```shell
Expand Down
2 changes: 1 addition & 1 deletion docs/lab1.md
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ If you've gone through all the steps of the investigation, and you're still unsu
file isn't being shared, you should read about the
[``enctype`` attribute of forms](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/form#enctype).

You'll see that the
You'll see that the

By default, a ``<form>`` element will use ``enctype="application/x-www-form-urlencoded"``.
However, as we found, that will not submit any ``<input type="file" />`` (or other file-based
Expand Down
4 changes: 2 additions & 2 deletions docs/lab2.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ cache.clear()
Let's consider what we know:

- The pages render correctly and there are no errors.
- The pages rendered "fast" earlier, but over time as the data set has grown,
- The pages rendered "fast" earlier, but over time as the data set has grown,
they have slowed down.


Expand Down Expand Up @@ -449,7 +449,7 @@ At this point it's clear there's a difference in functionality between how
``toggle_post_privacy`` and ``update_post`` save the data changes.
``toggle_post_privacy`` updates the instance using a ``QuerySet.update()``
call while ``update_post`` uses ``PostForm.save()`` which under the hood is
doing something like ``Model.save()``. If we read
doing something like ``Model.save()``. If we read
[the documentation for ``update``](https://docs.djangoproject.com/en/stable/ref/models/querysets/#update)
we'll see that there's a note that the ``post_save`` signal isn't emitted.
This explains why ``toggle_post_privacy`` doesn't delete the cached value
Expand Down
1 change: 1 addition & 0 deletions manage.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#!/usr/bin/env python
"""Django's command-line utility for administrative tasks."""

import os
import sys

Expand Down
2 changes: 1 addition & 1 deletion project/data/management/commands/fake_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def log(event):
logger.info(f"{event} - start")
yield
end = timezone.now()
logger.info(f"{event} - end, {(end-start).total_seconds()}s")
logger.info(f"{event} - end, {(end - start).total_seconds()}s")


class Command(BaseCommand):
Expand Down
26 changes: 13 additions & 13 deletions project/data/markdown.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from datetime import datetime, timezone
from datetime import UTC, datetime
from itertools import cycle

from faker import Faker
Expand Down Expand Up @@ -42,17 +42,17 @@ def generate_data(user, image_category, post_categories):
slug = slugify(title) + f"-{fake.pyint(10, 99999)}"
publish_at = (
fake.date_time_between_dates(
datetime_start=datetime(2020, 1, 1, tzinfo=timezone.utc),
datetime_end=datetime(2022, 10, 12, tzinfo=timezone.utc),
tzinfo=timezone.utc,
datetime_start=datetime(2020, 1, 1, tzinfo=UTC),
datetime_end=datetime(2022, 10, 12, tzinfo=UTC),
tzinfo=UTC,
)
if fake.pybool()
else None
)
created = fake.date_time_between_dates(
datetime_start=datetime(2020, 1, 1, tzinfo=timezone.utc),
datetime_end=datetime(2022, 10, 12, tzinfo=timezone.utc),
tzinfo=timezone.utc,
datetime_start=datetime(2020, 1, 1, tzinfo=UTC),
datetime_end=datetime(2022, 10, 12, tzinfo=UTC),
tzinfo=UTC,
)
if publish_at and publish_at < created:
created = publish_at
Expand Down Expand Up @@ -89,17 +89,17 @@ def generate_data(user, image_category, post_categories):
slug = slugify(title) + f"-{fake.pyint(10, 9999)}"
publish_at = (
fake.date_time_between_dates(
datetime_start=datetime(2020, 1, 1, tzinfo=timezone.utc),
datetime_end=datetime(2022, 10, 12, tzinfo=timezone.utc),
tzinfo=timezone.utc,
datetime_start=datetime(2020, 1, 1, tzinfo=UTC),
datetime_end=datetime(2022, 10, 12, tzinfo=UTC),
tzinfo=UTC,
)
if fake.pybool()
else None
)
created = fake.date_time_between_dates(
datetime_start=datetime(2020, 1, 1, tzinfo=timezone.utc),
datetime_end=datetime(2022, 10, 12, tzinfo=timezone.utc),
tzinfo=timezone.utc,
datetime_start=datetime(2020, 1, 1, tzinfo=UTC),
datetime_end=datetime(2022, 10, 12, tzinfo=UTC),
tzinfo=UTC,
)
if publish_at and publish_at < created:
created = publish_at
Expand Down
14 changes: 7 additions & 7 deletions project/data/subscribers.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from collections import OrderedDict
from datetime import datetime, timezone
from datetime import UTC, datetime
from functools import partial

from django.contrib.auth.models import User
Expand All @@ -25,9 +25,9 @@ def generate_data(categories: CategoryData):
)
user.email = f"{user.username}@example.com"
user.date_joined = fake.date_time_between_dates(
datetime_start=datetime(2020, 1, 1, tzinfo=timezone.utc),
datetime_end=datetime(2022, 10, 12, tzinfo=timezone.utc),
tzinfo=timezone.utc,
datetime_start=datetime(2020, 1, 1, tzinfo=UTC),
datetime_end=datetime(2022, 10, 12, tzinfo=UTC),
tzinfo=UTC,
)
users.append(user)
User.objects.bulk_create(users, ignore_conflicts=True)
Expand All @@ -50,9 +50,9 @@ def generate_data(categories: CategoryData):
for i in range(0, USER_COUNT, 50):
created_map = {
user_id: fake.date_time_between_dates(
datetime_start=datetime(2020, 1, 1, tzinfo=timezone.utc),
datetime_end=datetime(2022, 10, 12, tzinfo=timezone.utc),
tzinfo=timezone.utc,
datetime_start=datetime(2020, 1, 1, tzinfo=UTC),
datetime_end=datetime(2022, 10, 12, tzinfo=UTC),
tzinfo=UTC,
)
for user_id in user_ids[i : i + 50]
}
Expand Down
1 change: 0 additions & 1 deletion project/newsletter/migrations/0001_initial.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@


class Migration(migrations.Migration):

initial = True

dependencies = [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@


class Migration(migrations.Migration):

dependencies = [
("newsletter", "0001_initial"),
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@


class Migration(migrations.Migration):

dependencies = [
("newsletter", "0002_remove_post_is_draft_post_is_published_and_more"),
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@


class Migration(migrations.Migration):

dependencies = [
("newsletter", "0003_post_is_public_post_summary"),
]
Expand Down
1 change: 0 additions & 1 deletion project/newsletter/migrations/0005_auto_20220809_0012.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ def create_site(apps, schema_editor): # pragma: nocover


class Migration(migrations.Migration):

dependencies = [
("newsletter", "0004_alter_subscription_options_and_more"),
("sites", "0002_alter_domain_unique"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@


class Migration(migrations.Migration):

dependencies = [
("newsletter", "0005_auto_20220809_0012"),
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@


class Migration(migrations.Migration):

dependencies = [
("newsletter", "0006_alter_category_options_alter_subscription_categories"),
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@


class Migration(migrations.Migration):

dependencies = [
("newsletter", "0007_alter_subscriptionnotification_options_and_more"),
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@


class Migration(migrations.Migration):

dependencies = [
("newsletter", "0008_alter_post_categories"),
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@


class Migration(migrations.Migration):

dependencies = [
("newsletter", "0009_post_open_graph_description_post_open_graph_image"),
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@


class Migration(migrations.Migration):

dependencies = [
("newsletter", "0010_subscriptionnotification_read"),
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@


class Migration(migrations.Migration):

dependencies = [
(
"newsletter",
Expand Down
26 changes: 16 additions & 10 deletions project/newsletter/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,13 +155,13 @@ def __str__(self):
def __repr__(self):
return f"<Post title={self.title} slug={self.slug} is_published={self.is_published} created={self.created} updated={self.updated}>"

def get_absolute_url(self):
return reverse("newsletter:view_post", kwargs={"slug": self.slug})

@property
def publish_date(self):
return self.publish_at or self.created

def get_absolute_url(self):
return reverse("newsletter:view_post", kwargs={"slug": self.slug})


class SubscriptionQuerySet(models.QuerySet):
def for_user(self, user: User) -> Optional["Subscription"]:
Expand Down Expand Up @@ -206,6 +206,9 @@ class Subscription(TimestampedModel):
def __repr__(self):
return f"<Subscription id={self.id} user={self.user_id} created={self.created} updated={self.updated}>"

def __str__(self):
return f"Subscription id={self.id}"


class SubscriptionNotificationQuerySet(models.QuerySet):
def needs_notifications_sent_for_post(self, post: Post):
Expand Down Expand Up @@ -234,13 +237,6 @@ class SubscriptionNotification(TimestampedModel):
should be notified of the post.
"""

class Meta:
constraints = [
models.UniqueConstraint(
fields=["post", "subscription"], name="subscript_notif_uniq"
)
]

subscription = models.ForeignKey(
Subscription, related_name="notifications", on_delete=models.CASCADE
)
Expand All @@ -251,5 +247,15 @@ class Meta:
read = models.DateTimeField(null=True, blank=True)
objects = models.Manager.from_queryset(SubscriptionNotificationQuerySet)()

class Meta:
constraints = [
models.UniqueConstraint(
fields=["post", "subscription"], name="subscript_notif_uniq"
)
]

def __repr__(self):
return f"<SubscriptionNotification id={self.id} subscription={self.subscription_id} post={self.post_id} sent={self.sent} created={self.created} updated={self.updated}>"

def __str__(self):
return f"SubscriptionNotification id={self.id}"
1 change: 1 addition & 0 deletions project/newsletter/operations.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
This file contains create/update/writing operations.
"""

from datetime import timedelta

from django.core.cache import cache
Expand Down
1 change: 0 additions & 1 deletion project/newsletter/test_receivers.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@

class TestPostOnSave(DataTestCase):
def test_clears_cache_on_save(self):

post = Post.objects.create(
slug="receiver",
title="receiver",
Expand Down
Loading