Skip to content
Open
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: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,7 @@ screenshots
TODO.txt

.idea/

# app example
temp/
db.sqlite3
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,25 @@ class MyForm(forms.Form):
### Admin
The admin will kindly provide a simple [color picker](https://coloris.js.org/) for all color fields. :)

The `colorfield.admin.ColorAdminMixin` can be used in the admin model to display a box with the chosen color in the change list or also in the form when the field is not editable.

```python
from colorfield.admin import ColorAdminMixin
from colorfield.fields import ColorField
from django.contrib import admin
from django.db import models

class MyModel(models.Model):
color = ColorField(format="hexa")

@admin.register(MyModel)
class MyModelAdmin(ColorAdminMixin, admin.ModelAdmin):
list_display = ["id", "color"]
```

![django-colorfield-admin-list](./images/admin-list.png)
![django-colorfield-admin-form](./images/admin-form.png)

---

## Testing
Expand Down
Empty file added app_example/__init__.py
Empty file.
92 changes: 92 additions & 0 deletions app_example/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
from django.contrib import admin

from colorfield.admin import ColorAdminMixin

from . import forms, models


@admin.register(models.Color)
class ColorAdmin(ColorAdminMixin, admin.ModelAdmin):
list_display = [
"id",
"color_default_ro",
"color_null",
"color_rgb",
"color_rgba",
"color_choices",
"color_samples",
"color_image_hex",
"color_image_hexa",
"color_image_rgb",
"color_image_rgba",
]

# Make list editable to check how the list works along with RO fields
list_editable = [
"color_rgb",
"color_rgba",
]

# Add custom disabled field
form = forms.ColorForm

# These fields will display a box with the color in list and form
readonly_fields = [
"color_default_ro",
"color_image_hex",
"color_image_hexa",
"color_image_rgb",
"color_image_rgba",
]
fieldsets = [
(
"HEX, null & blank",
{
"fields": [
("color_default", "color_default_ro"),
"color_ro",
"color_null",
],
},
),
("RGB", {"fields": ["color_rgb", "color_rgba"]}),
("Choices", {"fields": ["color_choices", "color_samples"]}),
(
"Image",
{
"fields": [
"image",
"color_image_hex",
"color_image_hexa",
"color_image_rgb",
"color_image_rgba",
],
},
),
]

@admin.display(description="color default", ordering="color_default")
def color_default_ro(self, obj=None):
# custom field to be displayed instead of color_default field
# return empty value if None
return (obj.color_default if obj else None) or self.get_empty_value_display()

def _get_color_fields(self):
fields = list(super()._get_color_fields() or [])
# add custom field in list
return fields + ["color_default_ro"]

# Uncomment this method to display the change-form view as Read-Only.
# def has_change_permission(self, request, obj=None):
# return False


class ColorInlineAdmin(admin.TabularInline):
model = models.PaletteColor
extra = 0


@admin.register(models.Palette)
class PaletteAdmin(admin.ModelAdmin):
list_display = ["id", "name"]
inlines = [ColorInlineAdmin]
6 changes: 6 additions & 0 deletions app_example/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from django.apps import AppConfig as DjAppConfig


class AppExampleConfig(DjAppConfig):
name = "app_example"
default = True
13 changes: 13 additions & 0 deletions app_example/forms.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from django import forms

from colorfield.forms import ColorField

from .models import Color


class ColorForm(forms.ModelForm):
color_ro = ColorField(label="Color disabled", disabled=True, required=False)

class Meta:
model = Color
fields = forms.ALL_FIELDS
206 changes: 206 additions & 0 deletions app_example/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
# Generated by Django 5.2 on 2025-05-03 10:12

import colorfield.fields
import django.db.models.deletion
from django.db import migrations, models

from ..models import COLOR_PALETTE


class Migration(migrations.Migration):
initial = True

dependencies = []

operations = [
migrations.CreateModel(
name="Color",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"color_default",
colorfield.fields.ColorField(
blank=True,
default="",
image_field=None,
max_length=25,
samples=None,
),
),
(
"color_ro",
colorfield.fields.ColorField(
blank=True,
default="",
image_field=None,
max_length=25,
samples=None,
),
),
(
"color_null",
colorfield.fields.ColorField(
blank=True,
default=None,
image_field=None,
max_length=25,
null=True,
samples=None,
),
),
(
"color_rgb",
colorfield.fields.ColorField(
default="rgb(255, 255, 255)",
image_field=None,
max_length=25,
samples=None,
),
),
(
"color_rgba",
colorfield.fields.ColorField(
default="rgba(255, 255, 255, 1)",
image_field=None,
max_length=25,
samples=None,
),
),
(
"color_choices",
colorfield.fields.ColorField(
blank=True,
choices=COLOR_PALETTE,
default="",
image_field=None,
max_length=25,
samples=None,
),
),
(
"color_samples",
colorfield.fields.ColorField(
blank=True,
default="",
image_field=None,
max_length=25,
samples=COLOR_PALETTE,
),
),
("image", models.ImageField(blank=True, upload_to="temp")),
(
"color_image_hex",
colorfield.fields.ColorField(
blank=True,
default="",
editable=False,
image_field="image",
max_length=25,
samples=None,
),
),
(
"color_image_hexa",
colorfield.fields.ColorField(
blank=True,
default="",
editable=False,
image_field="image",
max_length=25,
samples=None,
),
),
(
"color_image_rgb",
colorfield.fields.ColorField(
blank=True,
default="",
editable=False,
image_field="image",
max_length=25,
samples=None,
),
),
(
"color_image_rgba",
colorfield.fields.ColorField(
blank=True,
default="",
editable=False,
image_field="image",
max_length=25,
samples=None,
),
),
],
),
migrations.CreateModel(
name="Palette",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("name", models.CharField(max_length=25)),
],
),
migrations.CreateModel(
name="PaletteColor",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"color",
colorfield.fields.ColorField(
default="#FFFFFF", image_field=None, max_length=25, samples=None
),
),
(
"color_choices",
colorfield.fields.ColorField(
choices=COLOR_PALETTE,
default="#FFFFFF",
image_field=None,
max_length=25,
samples=None,
),
),
(
"color_rgb",
colorfield.fields.ColorField(
default="rgb(255, 255, 255)",
image_field=None,
max_length=25,
samples=None,
),
),
(
"palette",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
to="app_example.palette",
),
),
],
),
]
Empty file.
Loading