Django application to handle chained model fields.
Project description
# Django Smart Selects
[![Build Status](https://travis-ci.org/digi604/django-smart-selects.svg?branch=master)](https://travis-ci.org/digi604/django-smart-selects)
[![Coverage Status](https://coveralls.io/repos/github/digi604/django-smart-selects/badge.svg?branch=master)](https://coveralls.io/github/digi604/django-smart-selects?branch=master)
This package allows you to quickly filter or group "chained" models by adding a custom foreign key or many to many field to your models. This will use an AJAX query to load only the applicable chained objects.
Keep in mind that this AJAX query exposes your data (only the models with chained fields) to all users who can access it. If you would like more control over this permission, the [`django-autocomplete-light`]() package is a great, high-quality package that enables the same functionality with permission checks.
## Chained Selects
Given the following model:
```python
class Continent(models.Model):
name = models.CharField(max_length=255)
class Country(models.Model):
continent = models.ForeignKey(Continent)
name = models.CharField(max_length=255)
class Location(models.Model):
continent = models.ForeignKey(Continent)
country = models.ForeignKey(Country)
area = models.ForeignKey(Area)
city = models.CharField(max_length=50)
street = models.CharField(max_length=100)
```
Once you select a continent, if you want only the countries on that continent to be available, you can use a `ChainedForeignKey` on the `Location` model:
```python
from smart_selects.db_fields import ChainedForeignKey
class Location(models.Model)
continent = models.ForeignKey(Continent)
country = ChainedForeignKey(
Country,
chained_field="continent",
chained_model_field="continent",
show_all=False,
auto_choose=True,
sort=True)
area = ForeignKey(Area)
city = models.CharField(max_length=50)
street = models.CharField(max_length=100)
```
### ChainedForeignKey options
#### chained_field (required)
The `chained_field` indicates the field on the same model that should be chained to. In the `Continent`, `Country`, `Location` example, `chained_field` is the name of the field `continent` in model `Location`.
```python
class Location(models.Model)
continent = models.ForeignKey(Continent)
```
#### chained_model_field (required)
The `chained_model_field` indicates the field of the chained model that corresponds to the model linked to by the `chained_field`. In the `Continent`, `Country`, `Location` example, `chained_model_field` is the name of field `continent` in Model `Country`.
```python
class Country(models.Model):
continent = models.ForeignKey(Continent)
```
#### show_all (optional)
`show_all` indicates if only the filtered results should be shown or if you also want to display the other results further down.
#### auto_choose (optional)
`auto_choose` indicates if auto select the choice when there is only one available choice.
#### `sort` (optional)
`sort` indicates if the result set should be sorted lexicographically or not. Disable if you want to use the `Model.ordering` option. Defaults to `True`.
## Chained ManyToMany Selects
The `ChainedManyToManyField` works as you would expect:
```python
from smart_selects.db_fields import ChainedManyToManyField
class Publication(models.Model):
name = models.CharField(max_length=255)
class Writer(models.Model):
name = models.CharField(max_length=255)
publications = models.ManyToManyField('Publication', blank=True, null=True)
class Book(models.Model):
publication = models.ForeignKey(Publication)
writer = ChainedManyToManyField(
Writer,
chained_field="publication",
chained_model_field="publications")
name = models.CharField(max_length=255)
```
### Using chained fields in the admin
Do **not** specify the field in the `ModelAdmin` `filter_horizontal` list. Instead, simply pass `horizontal=True` to the `ChainedManyToManyField`:
```python
from smart_selects.db_fields import ChainedManyToManyField
class Publication(models.Model):
name = models.CharField(max_length=255)
class Writer(models.Model):
name = models.CharField(max_length=255)
publications = models.ManyToManyField('Publication', blank=True, null=True)
class Book(models.Model):
publication = models.ForeignKey(Publication)
writer = ChainedManyToManyField(
Writer,
horizontal=True,
verbose_name='writer',
chained_field="publication",
chained_model_field="publications")
name = models.CharField(max_length=255)
```
### ChainedManyToManyField options
#### `chained_field` (required)
The `chained_field` indicates the field on the same model that should be chained to. In the `Publication`, `Writer`, `Book` example, `chained_field` is the name of the field `publication` in model `Book`.
```python
class Book(models.Model):
publication = models.ForeignKey(Publication)
```
#### `chained_model_field` (required)
The `chained_model_field` indicates the field of the chained model that corresponds to the model linked to by the `chained_field`. In the `Publication`, `Writer`, `Book` example, `chained_model_field` is the name of field `publications` in `Writer` model.
```python
class Writer(models.Model):
publications = models.ManyToManyField('Publication', blank=True, null=True)
```
#### `auto_choose` (optional)
`auto_choose` indicates if auto select the choice when there is only one available choice.
#### `horizontal` (optional)
This option will mixin Django's `FilteredSelectMultiple` to work in the Django admin as you expect
## Grouped Selects
If you have the following model:
```python
class Country(models.Model):
continent = models.ForeignKey(Continent)
class Location(models.Model):
continent = models.ForeignKey(Continent)
country = models.ForeignKey(Country)
```
And you want to group countries by their continent in the HTML select list, you can use a `GroupedForeignKey`:
```python
from smart_selects.db_fields import GroupedForeignKey
class Location(models.Model):
continent = models.ForeignKey(Continent)
country = GroupedForeignKey(Country, "continent")
```
## Installation
1. Add `smart_selects` to your `INSTALLED_APPS`
2. Add the `smart_selects` urls into your project's `urls.py`. This is needed for the `Chained Selects` and `Chained ManyToMany Selects`. For example:
```python
urlpatterns = patterns('',
url(r'^admin/', include(admin.site.urls)),
url(r'^chaining/', include('smart_selects.urls')),
)
```
## Settings
`USE_DJANGO_JQUERY`
: By default, `smart_selects` will use the bundled jQuery from Django 1.2's
admin area. Set `USE_DJANGO_JQUERY = False` to disable this behaviour.
`JQUERY_URL`
: By default, jQuery will be loaded from Google's CDN. If you would prefer to
use a different version put the full URL here. Set `JQUERY_URL = False` to disable loading jQuery.
## TODO
* Add permission checks to enable users to restrict who can use the chained fields.
* Add a ChainedCheckboxSelectMultiple widget and adjust `chainedm2m.js` and `chainedfk.js` to build checkboxes in that case
[![Build Status](https://travis-ci.org/digi604/django-smart-selects.svg?branch=master)](https://travis-ci.org/digi604/django-smart-selects)
[![Coverage Status](https://coveralls.io/repos/github/digi604/django-smart-selects/badge.svg?branch=master)](https://coveralls.io/github/digi604/django-smart-selects?branch=master)
This package allows you to quickly filter or group "chained" models by adding a custom foreign key or many to many field to your models. This will use an AJAX query to load only the applicable chained objects.
Keep in mind that this AJAX query exposes your data (only the models with chained fields) to all users who can access it. If you would like more control over this permission, the [`django-autocomplete-light`]() package is a great, high-quality package that enables the same functionality with permission checks.
## Chained Selects
Given the following model:
```python
class Continent(models.Model):
name = models.CharField(max_length=255)
class Country(models.Model):
continent = models.ForeignKey(Continent)
name = models.CharField(max_length=255)
class Location(models.Model):
continent = models.ForeignKey(Continent)
country = models.ForeignKey(Country)
area = models.ForeignKey(Area)
city = models.CharField(max_length=50)
street = models.CharField(max_length=100)
```
Once you select a continent, if you want only the countries on that continent to be available, you can use a `ChainedForeignKey` on the `Location` model:
```python
from smart_selects.db_fields import ChainedForeignKey
class Location(models.Model)
continent = models.ForeignKey(Continent)
country = ChainedForeignKey(
Country,
chained_field="continent",
chained_model_field="continent",
show_all=False,
auto_choose=True,
sort=True)
area = ForeignKey(Area)
city = models.CharField(max_length=50)
street = models.CharField(max_length=100)
```
### ChainedForeignKey options
#### chained_field (required)
The `chained_field` indicates the field on the same model that should be chained to. In the `Continent`, `Country`, `Location` example, `chained_field` is the name of the field `continent` in model `Location`.
```python
class Location(models.Model)
continent = models.ForeignKey(Continent)
```
#### chained_model_field (required)
The `chained_model_field` indicates the field of the chained model that corresponds to the model linked to by the `chained_field`. In the `Continent`, `Country`, `Location` example, `chained_model_field` is the name of field `continent` in Model `Country`.
```python
class Country(models.Model):
continent = models.ForeignKey(Continent)
```
#### show_all (optional)
`show_all` indicates if only the filtered results should be shown or if you also want to display the other results further down.
#### auto_choose (optional)
`auto_choose` indicates if auto select the choice when there is only one available choice.
#### `sort` (optional)
`sort` indicates if the result set should be sorted lexicographically or not. Disable if you want to use the `Model.ordering` option. Defaults to `True`.
## Chained ManyToMany Selects
The `ChainedManyToManyField` works as you would expect:
```python
from smart_selects.db_fields import ChainedManyToManyField
class Publication(models.Model):
name = models.CharField(max_length=255)
class Writer(models.Model):
name = models.CharField(max_length=255)
publications = models.ManyToManyField('Publication', blank=True, null=True)
class Book(models.Model):
publication = models.ForeignKey(Publication)
writer = ChainedManyToManyField(
Writer,
chained_field="publication",
chained_model_field="publications")
name = models.CharField(max_length=255)
```
### Using chained fields in the admin
Do **not** specify the field in the `ModelAdmin` `filter_horizontal` list. Instead, simply pass `horizontal=True` to the `ChainedManyToManyField`:
```python
from smart_selects.db_fields import ChainedManyToManyField
class Publication(models.Model):
name = models.CharField(max_length=255)
class Writer(models.Model):
name = models.CharField(max_length=255)
publications = models.ManyToManyField('Publication', blank=True, null=True)
class Book(models.Model):
publication = models.ForeignKey(Publication)
writer = ChainedManyToManyField(
Writer,
horizontal=True,
verbose_name='writer',
chained_field="publication",
chained_model_field="publications")
name = models.CharField(max_length=255)
```
### ChainedManyToManyField options
#### `chained_field` (required)
The `chained_field` indicates the field on the same model that should be chained to. In the `Publication`, `Writer`, `Book` example, `chained_field` is the name of the field `publication` in model `Book`.
```python
class Book(models.Model):
publication = models.ForeignKey(Publication)
```
#### `chained_model_field` (required)
The `chained_model_field` indicates the field of the chained model that corresponds to the model linked to by the `chained_field`. In the `Publication`, `Writer`, `Book` example, `chained_model_field` is the name of field `publications` in `Writer` model.
```python
class Writer(models.Model):
publications = models.ManyToManyField('Publication', blank=True, null=True)
```
#### `auto_choose` (optional)
`auto_choose` indicates if auto select the choice when there is only one available choice.
#### `horizontal` (optional)
This option will mixin Django's `FilteredSelectMultiple` to work in the Django admin as you expect
## Grouped Selects
If you have the following model:
```python
class Country(models.Model):
continent = models.ForeignKey(Continent)
class Location(models.Model):
continent = models.ForeignKey(Continent)
country = models.ForeignKey(Country)
```
And you want to group countries by their continent in the HTML select list, you can use a `GroupedForeignKey`:
```python
from smart_selects.db_fields import GroupedForeignKey
class Location(models.Model):
continent = models.ForeignKey(Continent)
country = GroupedForeignKey(Country, "continent")
```
## Installation
1. Add `smart_selects` to your `INSTALLED_APPS`
2. Add the `smart_selects` urls into your project's `urls.py`. This is needed for the `Chained Selects` and `Chained ManyToMany Selects`. For example:
```python
urlpatterns = patterns('',
url(r'^admin/', include(admin.site.urls)),
url(r'^chaining/', include('smart_selects.urls')),
)
```
## Settings
`USE_DJANGO_JQUERY`
: By default, `smart_selects` will use the bundled jQuery from Django 1.2's
admin area. Set `USE_DJANGO_JQUERY = False` to disable this behaviour.
`JQUERY_URL`
: By default, jQuery will be loaded from Google's CDN. If you would prefer to
use a different version put the full URL here. Set `JQUERY_URL = False` to disable loading jQuery.
## TODO
* Add permission checks to enable users to restrict who can use the chained fields.
* Add a ChainedCheckboxSelectMultiple widget and adjust `chainedm2m.js` and `chainedfk.js` to build checkboxes in that case
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
File details
Details for the file django-smart-selects-1.5.1.tar.gz
.
File metadata
- Download URL: django-smart-selects-1.5.1.tar.gz
- Upload date:
- Size: 19.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | f9d430bc3351b4c1dcd555d11b53b682b9b67f52ef93fecad73f45474fbf1b14 |
|
MD5 | 5fa300c1bfc20d1995ef2d2a9e2edc7c |
|
BLAKE2b-256 | 37321df568acc3fe562989914e18b34c89b4b105175d2ce76846ae14c4d00b6d |