django-querystring-tag


Namedjango-querystring-tag JSON
Version 1.0.3 PyPI version JSON
download
home_page
Summary
upload_time2023-01-22 11:31:28
maintainer
docs_urlNone
authorAndy Babic
requires_python>=3.7
licenseBSD-3-Clause
keywords django querystring get parameters pagination filter state-preserving link template tag util
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # django-querystring-tag

<p>
   <a href="https://pypi.org/project/django-querystring-tag/"><img alt="PyPi version" src="https://badgen.net/pypi/v/django-querystring-tag/"></a>
   <a href="https://github.com/ababic/django-querystring-tag/actions/workflows/test.yml"><img alt="Test workflow status" src="https://github.com/ababic/django-querystring-tag/actions/workflows/test.yml/badge.svg?branch=master"></a>
   <a href="https://codecov.io/gh/ababic/django-querystring-tag"><img alt="Coverage status" src="https://codecov.io/gh/ababic/django-querystring-tag/branch/master/graph/badge.svg?token=LDR7W1G2XC"></a>
   <a href="https://github.com/ababic/django-querystring-tag/blob/master/LICENSE"><img alt="License: BSD 3-Clause" src="https://img.shields.io/badge/License-BSD_3--Clause-blue.svg"></a>
   <a href="https://github.com/psf/black" target="blank"><img alt="Code style: Black" src="https://img.shields.io/badge/code%20style-black-000000.svg"></a>
</p>

This tiny package adds the `{% querystring %}` tag: A powerful, well tested template tag for modifying and rendering safe, suitably-encoded querystring values.

It's the clean and simple way to create pagination links, filters and other state-preserving links, without cluttering up your view code!

## Installation

1.  Install the package from pypi:

    **With Poetry**

    ```console
    $ poetry add django-querystring-tag
    ```

    **With pip**

    ```console
    $ pip install django-querystring-tag
    ```

2.  Add `"querystring_tag"` to the `INSTALLED_APPS` list in your Django project settings.

### Add querystring_tag to builtins (optional)

To use the `{% querystring %}` tag freely, without having to add `{% load querystring_tag %}` to all of your templates, you can add `"querystring_tag.templatetags.querystring_tag"` to the `['OPTIONS']['builtins']` list for your chosen template backend. [Here's an example](https://github.com/ababic/django-querystring-tag/blob/master/querystring_tag/testapp/settings.py#L36).

## How to use

First, load the tag into the template you want to use it in:

```
{% load querystring_tag %}
```

You can then use the tag like this:

```
{% querystring param_one='value' param_two+='add-to-existing' param_three-="remove-from-existing" %}
```

### The basics

1. The tag uses `request.GET` as the data source by default. Check out the [`source_data`](#source_data) option if you have other ideas.
2. The examples below are deliberately simple: You can make as many modifications in the same tag as you need. GO CRAZY!
3. You may be wondering "I want to use this in an include template, where the parameter name is dynamic. Will that work?". **Yes it will!** I know it's unusual, but you can [use tempalate variables for parameter names](#using-template-variables-for-parameter-names) too.
4. You don't want to preserve Google tracking parameters in links, do you? I thought not. Any parameters starting with `utm_` are removed by default. Add `remove_utm=False` if you would rather keep them.
5. You're probably not interested in preserving blank parameters in links either, are you? See? I read your mind! Blank values are removed by default too. Add `remove_blank=False` if you would rather keep them.
6. Want to variabalize the return value instead of rendering it? Go ahead any try the 'as' option. It works just as you would expect.

### Use `=` to set or replace a parameter 

The most common requirement is to completely replace the value for a specific parameter. This is done using a regular keyword argument, with an `=` operator between the parameter name and value. For example, if your querystring looked like this:

```
?q=test&baz=1
```

Any you wanted to add a `foo` variable with the value `bar`

```
{% querystring foo="bar" %}
```

Which would result in the following output:

```
?q=test&baz=1&foo=bar
```

### Use `-=` to remove values from a multi-value parameter 

When working with multi-value parameters, you may find yourself having to **remove** a specific value, without affecting any of the others.

In these situations, you can use the `-=` operator instead of the usual `=`. For example, if the current querystring looked something like this:

```
?q=test&bar=1&bar=2&bar=3
```

And you wanted to remove `&bar=2`, your querystring tag might look like this:

```
{% querystring bar-=2 %}
```

Which would result in the following output:

```
?q=test&bar=1&bar=3
```

If the specified value isn't present, the instruction will simply be ignored.

### Use `+=` to add values to a multi-value parameter

When working with multi-value parameters, you may find yourself having to **add** a specific value for a parameter, without affecting any of the others.

In these situations, you can use the `+=` operator instead of the usual `=`. For example, if the current querystring looked something like this:

```
?q=test&bar=1&bar=2&bar=3
```

And you wanted to add `&bar=4`, your querystring tag might look like this:

```
{% querystring bar+=4 %}
```

Which would result in the following output:

```
?q=test&bar=1&bar=2&bar=3&bar=4
```

If the specified value is already present, the instruction will simply be ignored.

### Use `only` to specify parameters you want to keep

Use `only` at the start of your `{% querystring %}` tag when you want the querystring to include values for specific parameters only.

For example, say the current querystring looked like this:

```
?q=keywords&group=articles&category=2&published_after=2022-01-01
```

And you only wanted to include the `q` and `group` params in a link. You could do:

```
{% querystring only 'q' 'group' %}
```

Which would result in the following output:

```
?q=keywords&group=articles
```

You can combine `only` with any number of modifications too. Just be sure to keep the `only` keyword and related parameter names as the left-most parameters, like so:

```
{% querystring only 'q' group="group_value" clear_session="true" %}
```

### Use `discard` to specify parameters you want to lose

Use `discard` at the start of your `{% querystring %}` tag when you want to exclude specific parameters from the querystring.

For example, say the current querystring looked like this:

```
?q=keywords&group=articles&category=2&published_after=2022-01-01
```

And you wanted to preserve everything except for `group` `published_after`. You could do:

```
{% querystring discard 'group' 'published_after' %}
```

Which would result in the following output:

```
?q=keywords&group=articles
```

You can combine `discard` with any number of modifications too. Just be sure to keep the `discard` keyword and related parameter names as the left-most parameters, like so:

```
{% querystring discard 'published_after' group="group_value" clear_session="true" %}
```

### Using template variables for parameter names

Unlike a lot of custom template tags, `{% querystring %}` supports the use of template variables in keys as well as values. For example, if the tag was being used to generate pagination links, and ``page_param_name`` and ``page_num`` were variables available in the template, you could use them both like so:

```
{% querystring page_param_name=page_num %}
```

### Supported value types

Values can be strings, booleans, integers, dates, datetimes, Django model instances, or iterables of either of these values.

When encountering a Django model instance, `{% querystring %}` will automatically take the `pk` value from it, and use that to modify the querystring. To use a different field value, you can use the tag's `model_value_field` option (see further down for details). Alternatively, you can add a `querystring_value_field` attribute to your model class. For example:

```python
class Category(models.Model):
    name = models.CharField(max_length=50)
    slug = models.SlugField(max_length=50, unique=True)

    # use 'slug' values in querystrings
    querystring_value_field = "slug"
```

### Specifying multiple values

As mentioned above, you can provide an iterable as a value to specify multiple values for a parameter at once. That could be a native Python type, such as a `list`, `tuple` or `set`, but could also be anything that implements the `__iter__` method to support iteration, for example, a `QuerySet`.

For example, if the context contained a variable ``tag_list``, which was list of strings (```['tag1', 'tag2', 'tag3']```), you can include all
of those values by referencing the list value. For example:

```
{% querystring tags=tag_list %}
```

The output of the above would be:

```
"?tags=tag1&amp;tags=tag2&amp;tags=tag3"
```

## Options reference

### `source_data`

**Supported value types**: `QueryDict`, `dict`, `str`

**Default value**: `request.GET`

The tag defaults to using ``request.GET`` as the data source for the querystring, but the `source_data` keyword argument can be used to specify use an alternative ``QueryDict``, ``dict`` or string value.

For example, say you were using a Django form to validate query data, and only want valid data to be included. You could use the Form's `cleaned_data` to generate a querystring instead:

```
{% querystring source_data=form.cleaned_data page=2 %}
```

### `remove_blank`

**Supported value types**: `bool`

**Default value**: `True`

Any parameter values with a value of `None` or `""` (an empty string) are removed from the querystring default.

To retain blank values, include `remove_blank=False` in your `{% querystring %}` tag.

### `remove_utm`

**Supported value types**: `bool`

**Default value**: `True`

Parameter names starting with `"utm_"` (the format used for Google Analytics tracking parameters) are exluded from the generated querystrings by default, as it's unlikley that you'll want these to be repeated in links to other pages.

To retain these parameters instead, include `remove_utm=False` in your `{% querystring %}` tag.

### `model_value_field`

**Supported value types**: `str`

**Default value**: `"pk"`

By default, when encountering a Django model instance as a value, `{% querystring %}` will take the `pk` value from the instance to use in the querystring. If you'd like to use a different field value, you can use the `model_value_field` option to specify an alternative field.

For example, if the model had a `slug` field that you were using as the public-facing identifier, you could specify that `slug` values be used in the querystring, like so:

```
{% querystring tags=tag_queryset model_field_value='slug' %}
```

## Testing the code locally

If you have a recent version of Python 3 installed, you can use a simple virtualenv to run tests locally. After cloning the repository, navigate to the project's root directory on your machine, then run the following:

### Set up the virtualenv

```console
$ virtualenv venv
$ source venv/bin/activate
$ pip install -e '.[test]' -U
```

### Run tests

```console
$ pytest
```

### When you're done

```console
$ deactivate
```

            

Raw data

            {
    "_id": null,
    "home_page": "",
    "name": "django-querystring-tag",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.7",
    "maintainer_email": "",
    "keywords": "django querystring GET parameters pagination filter state-preserving link template tag util",
    "author": "Andy Babic",
    "author_email": "andyjbabic@gmail.com",
    "download_url": "https://files.pythonhosted.org/packages/f7/11/3f472e269fcccd7c63dd025e838016ea014d3fa5cb0895371c2f61c6e2aa/django-querystring-tag-1.0.3.tar.gz",
    "platform": null,
    "description": "# django-querystring-tag\n\n<p>\n   <a href=\"https://pypi.org/project/django-querystring-tag/\"><img alt=\"PyPi version\" src=\"https://badgen.net/pypi/v/django-querystring-tag/\"></a>\n   <a href=\"https://github.com/ababic/django-querystring-tag/actions/workflows/test.yml\"><img alt=\"Test workflow status\" src=\"https://github.com/ababic/django-querystring-tag/actions/workflows/test.yml/badge.svg?branch=master\"></a>\n   <a href=\"https://codecov.io/gh/ababic/django-querystring-tag\"><img alt=\"Coverage status\" src=\"https://codecov.io/gh/ababic/django-querystring-tag/branch/master/graph/badge.svg?token=LDR7W1G2XC\"></a>\n   <a href=\"https://github.com/ababic/django-querystring-tag/blob/master/LICENSE\"><img alt=\"License: BSD 3-Clause\" src=\"https://img.shields.io/badge/License-BSD_3--Clause-blue.svg\"></a>\n   <a href=\"https://github.com/psf/black\" target=\"blank\"><img alt=\"Code style: Black\" src=\"https://img.shields.io/badge/code%20style-black-000000.svg\"></a>\n</p>\n\nThis tiny package adds the `{% querystring %}` tag: A powerful, well tested template tag for modifying and rendering safe, suitably-encoded querystring values.\n\nIt's the clean and simple way to create pagination links, filters and other state-preserving links, without cluttering up your view code!\n\n## Installation\n\n1.  Install the package from pypi:\n\n    **With Poetry**\n\n    ```console\n    $ poetry add django-querystring-tag\n    ```\n\n    **With pip**\n\n    ```console\n    $ pip install django-querystring-tag\n    ```\n\n2.  Add `\"querystring_tag\"` to the `INSTALLED_APPS` list in your Django project settings.\n\n### Add querystring_tag to builtins (optional)\n\nTo use the `{% querystring %}` tag freely, without having to add `{% load querystring_tag %}` to all of your templates, you can add `\"querystring_tag.templatetags.querystring_tag\"` to the `['OPTIONS']['builtins']` list for your chosen template backend. [Here's an example](https://github.com/ababic/django-querystring-tag/blob/master/querystring_tag/testapp/settings.py#L36).\n\n## How to use\n\nFirst, load the tag into the template you want to use it in:\n\n```\n{% load querystring_tag %}\n```\n\nYou can then use the tag like this:\n\n```\n{% querystring param_one='value' param_two+='add-to-existing' param_three-=\"remove-from-existing\" %}\n```\n\n### The basics\n\n1. The tag uses `request.GET` as the data source by default. Check out the [`source_data`](#source_data) option if you have other ideas.\n2. The examples below are deliberately simple: You can make as many modifications in the same tag as you need. GO CRAZY!\n3. You may be wondering \"I want to use this in an include template, where the parameter name is dynamic. Will that work?\". **Yes it will!** I know it's unusual, but you can [use tempalate variables for parameter names](#using-template-variables-for-parameter-names) too.\n4. You don't want to preserve Google tracking parameters in links, do you? I thought not. Any parameters starting with `utm_` are removed by default. Add `remove_utm=False` if you would rather keep them.\n5. You're probably not interested in preserving blank parameters in links either, are you? See? I read your mind! Blank values are removed by default too. Add `remove_blank=False` if you would rather keep them.\n6. Want to variabalize the return value instead of rendering it? Go ahead any try the 'as' option. It works just as you would expect.\n\n### Use `=` to set or replace a parameter \n\nThe most common requirement is to completely replace the value for a specific parameter. This is done using a regular keyword argument, with an `=` operator between the parameter name and value. For example, if your querystring looked like this:\n\n```\n?q=test&baz=1\n```\n\nAny you wanted to add a `foo` variable with the value `bar`\n\n```\n{% querystring foo=\"bar\" %}\n```\n\nWhich would result in the following output:\n\n```\n?q=test&baz=1&foo=bar\n```\n\n### Use `-=` to remove values from a multi-value parameter \n\nWhen working with multi-value parameters, you may find yourself having to **remove** a specific value, without affecting any of the others.\n\nIn these situations, you can use the `-=` operator instead of the usual `=`. For example, if the current querystring looked something like this:\n\n```\n?q=test&bar=1&bar=2&bar=3\n```\n\nAnd you wanted to remove `&bar=2`, your querystring tag might look like this:\n\n```\n{% querystring bar-=2 %}\n```\n\nWhich would result in the following output:\n\n```\n?q=test&bar=1&bar=3\n```\n\nIf the specified value isn't present, the instruction will simply be ignored.\n\n### Use `+=` to add values to a multi-value parameter\n\nWhen working with multi-value parameters, you may find yourself having to **add** a specific value for a parameter, without affecting any of the others.\n\nIn these situations, you can use the `+=` operator instead of the usual `=`. For example, if the current querystring looked something like this:\n\n```\n?q=test&bar=1&bar=2&bar=3\n```\n\nAnd you wanted to add `&bar=4`, your querystring tag might look like this:\n\n```\n{% querystring bar+=4 %}\n```\n\nWhich would result in the following output:\n\n```\n?q=test&bar=1&bar=2&bar=3&bar=4\n```\n\nIf the specified value is already present, the instruction will simply be ignored.\n\n### Use `only` to specify parameters you want to keep\n\nUse `only` at the start of your `{% querystring %}` tag when you want the querystring to include values for specific parameters only.\n\nFor example, say the current querystring looked like this:\n\n```\n?q=keywords&group=articles&category=2&published_after=2022-01-01\n```\n\nAnd you only wanted to include the `q` and `group` params in a link. You could do:\n\n```\n{% querystring only 'q' 'group' %}\n```\n\nWhich would result in the following output:\n\n```\n?q=keywords&group=articles\n```\n\nYou can combine `only` with any number of modifications too. Just be sure to keep the `only` keyword and related parameter names as the left-most parameters, like so:\n\n```\n{% querystring only 'q' group=\"group_value\" clear_session=\"true\" %}\n```\n\n### Use `discard` to specify parameters you want to lose\n\nUse `discard` at the start of your `{% querystring %}` tag when you want to exclude specific parameters from the querystring.\n\nFor example, say the current querystring looked like this:\n\n```\n?q=keywords&group=articles&category=2&published_after=2022-01-01\n```\n\nAnd you wanted to preserve everything except for `group` `published_after`. You could do:\n\n```\n{% querystring discard 'group' 'published_after' %}\n```\n\nWhich would result in the following output:\n\n```\n?q=keywords&group=articles\n```\n\nYou can combine `discard` with any number of modifications too. Just be sure to keep the `discard` keyword and related parameter names as the left-most parameters, like so:\n\n```\n{% querystring discard 'published_after' group=\"group_value\" clear_session=\"true\" %}\n```\n\n### Using template variables for parameter names\n\nUnlike a lot of custom template tags, `{% querystring %}` supports the use of template variables in keys as well as values. For example, if the tag was being used to generate pagination links, and ``page_param_name`` and ``page_num`` were variables available in the template, you could use them both like so:\n\n```\n{% querystring page_param_name=page_num %}\n```\n\n### Supported value types\n\nValues can be strings, booleans, integers, dates, datetimes, Django model instances, or iterables of either of these values.\n\nWhen encountering a Django model instance, `{% querystring %}` will automatically take the `pk` value from it, and use that to modify the querystring. To use a different field value, you can use the tag's `model_value_field` option (see further down for details). Alternatively, you can add a `querystring_value_field` attribute to your model class. For example:\n\n```python\nclass Category(models.Model):\n    name = models.CharField(max_length=50)\n    slug = models.SlugField(max_length=50, unique=True)\n\n    # use 'slug' values in querystrings\n    querystring_value_field = \"slug\"\n```\n\n### Specifying multiple values\n\nAs mentioned above, you can provide an iterable as a value to specify multiple values for a parameter at once. That could be a native Python type, such as a `list`, `tuple` or `set`, but could also be anything that implements the `__iter__` method to support iteration, for example, a `QuerySet`.\n\nFor example, if the context contained a variable ``tag_list``, which was list of strings (```['tag1', 'tag2', 'tag3']```), you can include all\nof those values by referencing the list value. For example:\n\n```\n{% querystring tags=tag_list %}\n```\n\nThe output of the above would be:\n\n```\n\"?tags=tag1&amp;tags=tag2&amp;tags=tag3\"\n```\n\n## Options reference\n\n### `source_data`\n\n**Supported value types**: `QueryDict`, `dict`, `str`\n\n**Default value**: `request.GET`\n\nThe tag defaults to using ``request.GET`` as the data source for the querystring, but the `source_data` keyword argument can be used to specify use an alternative ``QueryDict``, ``dict`` or string value.\n\nFor example, say you were using a Django form to validate query data, and only want valid data to be included. You could use the Form's `cleaned_data` to generate a querystring instead:\n\n```\n{% querystring source_data=form.cleaned_data page=2 %}\n```\n\n### `remove_blank`\n\n**Supported value types**: `bool`\n\n**Default value**: `True`\n\nAny parameter values with a value of `None` or `\"\"` (an empty string) are removed from the querystring default.\n\nTo retain blank values, include `remove_blank=False` in your `{% querystring %}` tag.\n\n### `remove_utm`\n\n**Supported value types**: `bool`\n\n**Default value**: `True`\n\nParameter names starting with `\"utm_\"` (the format used for Google Analytics tracking parameters) are exluded from the generated querystrings by default, as it's unlikley that you'll want these to be repeated in links to other pages.\n\nTo retain these parameters instead, include `remove_utm=False` in your `{% querystring %}` tag.\n\n### `model_value_field`\n\n**Supported value types**: `str`\n\n**Default value**: `\"pk\"`\n\nBy default, when encountering a Django model instance as a value, `{% querystring %}` will take the `pk` value from the instance to use in the querystring. If you'd like to use a different field value, you can use the `model_value_field` option to specify an alternative field.\n\nFor example, if the model had a `slug` field that you were using as the public-facing identifier, you could specify that `slug` values be used in the querystring, like so:\n\n```\n{% querystring tags=tag_queryset model_field_value='slug' %}\n```\n\n## Testing the code locally\n\nIf you have a recent version of Python 3 installed, you can use a simple virtualenv to run tests locally. After cloning the repository, navigate to the project's root directory on your machine, then run the following:\n\n### Set up the virtualenv\n\n```console\n$ virtualenv venv\n$ source venv/bin/activate\n$ pip install -e '.[test]' -U\n```\n\n### Run tests\n\n```console\n$ pytest\n```\n\n### When you're done\n\n```console\n$ deactivate\n```\n",
    "bugtrack_url": null,
    "license": "BSD-3-Clause",
    "summary": "",
    "version": "1.0.3",
    "split_keywords": [
        "django",
        "querystring",
        "get",
        "parameters",
        "pagination",
        "filter",
        "state-preserving",
        "link",
        "template",
        "tag",
        "util"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "ae7280a8c95a568d9f5d75f5a11490d2bbb66738a5990e7c316d48d332182c51",
                "md5": "198241c22be07c51b266a8e0ed3687b5",
                "sha256": "fef92f0279e683d8ce3c9bb996f8d978fe898545e796d6941256e5eddc565226"
            },
            "downloads": -1,
            "filename": "django_querystring_tag-1.0.3-py2.py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "198241c22be07c51b266a8e0ed3687b5",
            "packagetype": "bdist_wheel",
            "python_version": "py2.py3",
            "requires_python": ">=3.7",
            "size": 16136,
            "upload_time": "2023-01-22T11:31:26",
            "upload_time_iso_8601": "2023-01-22T11:31:26.949461Z",
            "url": "https://files.pythonhosted.org/packages/ae/72/80a8c95a568d9f5d75f5a11490d2bbb66738a5990e7c316d48d332182c51/django_querystring_tag-1.0.3-py2.py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "f7113f472e269fcccd7c63dd025e838016ea014d3fa5cb0895371c2f61c6e2aa",
                "md5": "4bf22cbfbe36d33cf0e2db8fe5e3b32b",
                "sha256": "86414606d6b59b9e9f65f0bc9e523318cbf71e75efa19074d1553b942c6a8f1e"
            },
            "downloads": -1,
            "filename": "django-querystring-tag-1.0.3.tar.gz",
            "has_sig": false,
            "md5_digest": "4bf22cbfbe36d33cf0e2db8fe5e3b32b",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.7",
            "size": 14837,
            "upload_time": "2023-01-22T11:31:28",
            "upload_time_iso_8601": "2023-01-22T11:31:28.705410Z",
            "url": "https://files.pythonhosted.org/packages/f7/11/3f472e269fcccd7c63dd025e838016ea014d3fa5cb0895371c2f61c6e2aa/django-querystring-tag-1.0.3.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-01-22 11:31:28",
    "github": false,
    "gitlab": false,
    "bitbucket": false,
    "lcname": "django-querystring-tag"
}
        
Elapsed time: 0.08585s