Skip to content

Commit

Permalink
Merge pull request #79 from hapytex/feature/highlight
Browse files Browse the repository at this point in the history
Feature/highlight
  • Loading branch information
KommuSoft authored Oct 14, 2024
2 parents 6b56197 + dacd0b9 commit bc01281
Show file tree
Hide file tree
Showing 15 changed files with 37 additions and 28 deletions.
11 changes: 10 additions & 1 deletion .github/workflows/build-site.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,19 @@ jobs:
- name: look for todos
run: "! grep -i -P '<pre\\s*>|TODO|[?]{3,}' */*.md"

linux3:
name: Look for code not highlighted
runs-on: ubuntu-latest
steps:
- name: checkout code
uses: actions/checkout@v2.3.1
- name: look for unhighlighted code
run: "! grep -Pz '\\n\\n```\\n' */*.md"

linux3:
name: Deploy website
runs-on: ubuntu-latest
needs: [linux1, linux2]
needs: [linux1, linux2, linux3]
if: github.ref == 'refs/heads/master'
steps:
- name: update package database
Expand Down
4 changes: 2 additions & 2 deletions antipattern/fill-the-primary-key-gaps.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ A frequently asked question is how to "*fill the gaps*" in the primary key range

It is understandable that people want to automatically reassign the primary keys of records that have been reassigned. Strictly speaking a database could easily do that, and since the database does not do that, we could run a query to automatically look for the "first" gap. Indeed, we can find the primary key we want with:

```python3
```python
# do not use this

from django.db.models import Exists, F, OuterRef
Expand All @@ -31,7 +31,7 @@ But a more severe problem is that now the URL `/article/2` no longer points to t

But the most severe problem is that there can still be a lot of items referring to the old article, that now perhaps refer to the new article. Indeed, imagine that you have a [**`GenericForeignKey`**&nbsp;<sup>\[Django-doc\]</sup>](https://docs.djangoproject.com/en/stable/ref/contrib/contenttypes/#django.contrib.contenttypes.fields.GenericForeignKey), if there is no [**`GenericRelation`**&nbsp;<sup>\[Django-doc\]</sup>](https://docs.djangoproject.com/en/stable/ref/contrib/contenttypes/#django.contrib.contenttypes.fields.GenericRelation), it will *not* be triggered to remove the objects. Indeed, imagine that we have a `Tag` model with:

```python3
```python
class TaggedItem(models.Model):
tag = models.SlugField()
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
Expand Down
2 changes: 1 addition & 1 deletion antipattern/filter-on-arbitrary-input-like-request-get.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ solinks: []

A "lazy" way to allow filtering on options is to pass `request.GET`, `request.POST`, `request.query_params` as named parameters to the filter clause. For example with:

```python3
```python
MyModel.objects.filter(**request.GET)
```

Expand Down
4 changes: 2 additions & 2 deletions antipattern/imports.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ solinks: []

Often it's necessary to import modules used in your code and often you see them imported as below:

```python3
```python
from projects.models import Project
from django.views.generic import *

Expand All @@ -33,7 +33,7 @@ Secondly, you are importing everything from `django.views.generic` using `*` whi

The code above can be re-written thus:

```python3
```python
from django.views.generic import ListView
from .models import Project

Expand Down
2 changes: 1 addition & 1 deletion antipattern/manually-constructing-a-slug.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ solinks: []

Sometimes, people construct slugs manually, for example in a view with:

```python3
```python
model_object.slug = model_object.title.replace(' ', '-')
```

Expand Down
6 changes: 3 additions & 3 deletions antipattern/non-atomic-jsonfield-s.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ A final reason not to use JSON blobs is that validation of the structure of JSON

If the field has a certain structure, convert that structure into models, and *linearize* data. Indeed, imagine that we have a model with:

```python3
```python
from django.conf import settings
from django.db import models

Expand All @@ -47,7 +47,7 @@ where `lines` for example look like:
we can convert this to an extra model that has a `ForeignKey` to a `Product` and where we store the quantity, like:


```python3
```python
class Order(models.Model):
customer = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.PROTECT)

Expand All @@ -60,7 +60,7 @@ class OrderLine(models.Model):

here we can efficiently filter for orders with a `product_id=14` in it with:

```python3
```python
Order.objects.filter(lines__product_id=14)
```

Expand Down
2 changes: 1 addition & 1 deletion antipattern/passing-function-references-to-reverse.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ solinks: ['https://stackoverflow.com/questions/78035103/in-django-is-it-possible

The [**<code>reverse(&hellip;)</code>** function&nbsp;<sup>\[Django-doc\]</sup>](https://docs.djangoproject.com/en/stable/ref/urlresolvers/#reverse) allows to pass the names of views as well as references to functions. Indeed, for example with:

```python3
```python
#app_name/urls.py

from app_name.views import some_view
Expand Down
6 changes: 3 additions & 3 deletions antipattern/plural-model-class-names.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ solinks: []

Often people write model classes with a plural name. For example:

```python3
```python
from django.db import models

class Cars(models.Model):
Expand Down Expand Up @@ -39,7 +39,7 @@ and incorrect plural nouns.
It also makes queries look grammatically incorrect English, for example,
one queries with:

```python3
```python
Cars.objects.all()
```

Expand All @@ -53,7 +53,7 @@ well.
For related models, this results in ugly looking names as well, for example one
queries with:

```python3
```python
ford.cars_set.all()
```

Expand Down
4 changes: 2 additions & 2 deletions antipattern/run-makemigrations-in-production.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Occasionally people think it is a good idea to also run `makemigrations` in the

Migrating the database is a *non-trivial problem*. There are multiple ways how you can migrate a database to get the model in sync with the database. Indeed, imagine that you have a model:

```python3
```python
from django.db import models


Expand All @@ -27,7 +27,7 @@ class MyModel(models.Model):

and we now change the model to:

```python3
```python
from django.db import models


Expand Down
4 changes: 2 additions & 2 deletions antipattern/signals.md
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ predictable.
One can construct a [*data migration*&nbsp;<sup>[Django-doc]</sup>](https://docs.djangoproject.com/en/dev/howto/writing-migrations/#how-to-create-database-migrations),
such migration could populate a database table, for example:

```python3
```python
from django.apps import apps as global_apps
from django.db import migrations

Expand Down Expand Up @@ -201,7 +201,7 @@ and `Author`s grows, then this can become a performance bottleneck.
Another option might be to encapsulate the handler logic in a specific function. For example if we want to count the number of
books of an `Author` each time we save/update a `Book`, we can implement the logic:

```python3
```python
def update_book(book):
author = book.author
author.num_books = author.books.count()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ each process their part of the composite form.
For example one can make two forms to fill in data about the father and
the mother with:

```python3
```python
from django import forms

class FatherForm(forms.Form):
Expand Down
4 changes: 2 additions & 2 deletions pattern/dictionary-lookups-for-the-database.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ solinks: []

It happens occasionally we want to perform a lookup with a dictionary for model records. Indeed, imagine we have a dictionary:

```python3
```python
prices = {
13: 2.0,
14: 25.0,
Expand All @@ -25,7 +25,7 @@ In an ideal scenario, we store the prices in the database, for example with as a

In a seldom scenario, it might however not be possible, for example because there is no such table, or because we are not allowed to make modifications to the database, or because we want to calculate a price changes, without storing the prices. In that case we thus want to work with a dictionary lookup. The following will however *not* work:

```python3
```python
# will *not* work
Product.objects.annotate(price=prices.get(F('pk')))
```
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Often this is also checked in a case-*in*sensitive way, such that `'apple'` and

Usually we have a list of items that we want to match with that field, for example:

```python3
```python
fruits = ['apple', 'blueberry', 'coconut', 'dragonfruit']
```

Expand All @@ -28,7 +28,7 @@ We can not make use of the [**`__in`** lookup&nbsp;<sup>[Django-doc]</sup>](http
since this will only match items that contain exactly the name of one fruit in case-sensitive way.
This thus means that the content should be `'apple'`, not <s>`'APPLE'`</s>, <s>`'Apple'`</s>, <s>`'An apple'`</s>, etc.:

```python3
```python
Post.objects.filter(
content__in=fruits
)
Expand Down
6 changes: 3 additions & 3 deletions pattern/querying-in-the-opposite-direction.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ solinks: ["https://stackoverflow.com/questions/78132711/i-need-a-django-filter-q

Django's ORM is quite expressive, and lookups can be used to filter in a specific way, for example:

```python3
```python
MyModel.objects.filter(title__regex='^[0-9]+$')
```

Expand All @@ -25,7 +25,7 @@ At the moment of writing there is no reverse lookup: we can not perform a `MyMod

A simple, but a bit "*ugly*" way to solve this is by using [**<code>.alias(&hellip;)</code>**&nbsp;<sup>\[Django-doc\]</sup>](https://docs.djangoproject.com/en/stable/ref/models/querysets/#alias) to "inject" the value as a field in the queryset and then thus query with that "field", we can then use an [**`F`** expression&nbsp;<sup>\[Django-doc\]](https://docs.djangoproject.com/en/stable/ref/models/expressions/#django.db.models.F) to refer to the `pattern` field. This thus then looks like:

```python3
```python
from django.db.models import F, Value

MyModel.objects.alias(val=Value('test_string')).filter(val__regex=F('pattern'))
Expand All @@ -35,7 +35,7 @@ Since we use <code>.alias(&hellip;)</code> the value will not appear in the `SEL

But probably a more robust, and clearer way to show what we are doing, is building a query object like Django does behind the curtains when we perform lookups. Indeed, if we write `pattern__regex`, it makes a lookup for a field named `pattern`, and inspects what type of field it is. For a `CharField` a different set of lookups will be "registered". If we then write `__regex`, it will start looking for a lookup registered at this field with the name `regex`. These lookups typically reside in the `django.db.models.lookups` module. For this specific case, this is the `Regex` class. We thus can construct such query with:

```python3
```python
from django.db.models import F, Value
from django.db.models.lookups import Regex

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Often not all fields specified in a model are specified through a form.
These for example originate for example through the path, or we make use of the
logged in user. Take for example the following model:

```python3
```python
from django.conf import settings
from django.db import models

Expand All @@ -26,7 +26,7 @@ The form will normally only take the `comment` as field, not the `post` and
`author`. We can for example specify the primary key of the post in the path,
and the author is normally the logged in user. The form thus looks like:

```python3
```python
from django import forms

class CommentForm(forms.ModelForm):
Expand Down

0 comments on commit bc01281

Please sign in to comment.