Model field and form field


class galleryfield.fields.GalleryField(target_model=None, *args, **kwargs)[source]

Bases: django.db.models.fields.json.JSONField

This is a model field which saves the id of images.


target_model (str, optional.) – A string in the form of "app_label.model_name", which can be loaded by django.apps.get_model() (see Django docs), defaults to None. If None, galleryfield.BuiltInGalleryImage will be used. If set, it should be a valid image model.

GalleryField and GalleryImages

class galleryfield.fields.GalleryImages[source]

When you access a GalleryField on a model, you are given an instance of GalleryImages as a proxy for accessing the underlying images. Basically, a GalleryImages instance is a list of pk of the image model instances defined by target_model. That means we can manipulate the field value with method such as slice, append() and extend().

For example:

>>> g = Demogallery.objects.first()
>>> g.images
[2, 1, 3]
>>> len(g.images)
>>> g.images.append(4)  # assuming there is BuiltInGalleryImage with pk=4
>>> g.images
>>> [2, 1, 3, 4]

Besides that, GalleryField includes an objects attribute:


An queryset of image instances.

That means we can do chained query to the attribute. Sample usage:

>>> g.images.objects.all()
<QuerySet [<BuiltInGalleryImage: BuiltInGalleryImage object (2)>, <BuiltInGalleryImage:
BuiltInGalleryImage object (1)>, <BuiltInGalleryImage: BuiltInGalleryImage object (3)>,
<BuiltInGalleryImage: BuiltInGalleryImage object (4)>]>
>>> g.images.objects.filter(pk__lte=2)
<QuerySet [<BuiltInGalleryImage: BuiltInGalleryImage object (2)>, <BuiltInGalleryImage:
BuiltInGalleryImage object (1)>]>
>>> g.images.objects.filter(pk__gte=5)
<QuerySet []>

With the objects attribute, it’s also handy to render images contained in the field. For example, we use code like to the following snippet in the template which renders detailed view of demo.models.DemoGallery instances:

{% for obj in object.images.objects.all %}
  <a href="{{ obj.image.url }}">
{% endfor %}

where object is an instance of demo.models.DemoGallery.


class galleryfield.fields.GalleryFormField(max_number_of_images=None, **kwargs)[source]

Bases: django.forms.fields.JSONField

The default formfield for galleryfield.fields.GalleryField.

  • max_number_of_images (int, optional.) – Max allowed number of images, defaults to None, which means unlimited.

  • kwargs

    Besides the options from parent class, the following were added:

    • target_model: str, a valid target image model which can be loaded by apps.get_model. When this field is used in the model form, it is auto configured by the model instance.

      However, if this field is used as a non-model form field, when not specified, it will use the built-in default target image model galleryfield.BuiltInGalleryImage.

    • widget: if not specified, defaults to GalleryWidget with default values.


If target_model not specified when initializing, an info will be logged to the stdout, which can be turned off by adding gallery_form_field.I001 in settings.SILENCED_SYSTEM_CHECKS.


galleryfield.fields.GalleryFormField is not supposed to be used independently (i.e., as a non-modelform field). The most possible cases for us to access the formfield are in the modelform configurations. For example:

class MyGalleryForm(forms.ModelForm):
    class Meta:
        model = MyGallery
        fields = ["images"]

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.fields["images"].required = False
        self.fields["images"].max_number_of_images = 2

        # from django.forms.widgets import Textarea
        # self.fields["images"].widget = Textarea()  # Use Textarea as widget


If you want to use galleryfield.fields.GalleryFormField as a non-modelform field, remember to initialize the field with a key word argument like target_model="my_app.MyImage", otherwise it will use galleryfield.BuiltInGalleryImage as the target_model. Also, keep in mind that the cleaned_data of the field only contains the pk of the image model instances.