pythondjangodjango-modelsdjango-admindjango-postgresql

Django Admin Model ArrayField Change Delimiter


My model looks like this:

from django.contrib.postgres.fields import ArrayField
class Trigger(models.Model):
    solutions = ArrayField(models.TextField(blank=True, null=True), blank=True, null=True, help_text='some helpful text')

This allows me to enter a list of solutions separated by a comma by default. For example: I can enter in that textfield:

1. watch out for dust.,
2. keep away from furry animals.,

This does create a list of two separate string items. However, if a solution text itself contains a comma, for example:

1. cockroaches, polens and molds might be harmful. 

This will create two separate solution lines, because of the existence of a comma in that sentence.

How do I tell django to use a different delimiter than comma as it would be almost certainly a part of sentences. How can I use a separator like '|'? I looked inside the arrayfield class, but it doesn't allow any separator.


Solution

  • Some relevant documentation:

    If you're using built in forms on the admin site, or using a ModelForm without customising any fields then the field is probably automatically using the SimpleArrayField form field. It looks like you can override the delimiter character. The documentation states this caveat:

    The field does not support escaping of the delimiter, so be careful in cases where the delimiter is a valid character in the underlying field. The delimiter does not need to be only one character.


    Anyways, you could do this by providing a custom form like this...

    # forms.py
    
    from django import forms
    from .models import Trigger
    
    
    class TriggerForm(forms.ModelForm):
        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
            self.fields['solutions'].delimiter = '|'  # Or whichever other character you want.
    
        class Meta:
            model = Trigger
            fields = '__all__'
    

    And if this is for use in the admin site...

    # admin.py
    
    from django.contrib import admin
    from .forms import TriggerForm
    from .models import Trigger
    
    
    @admin.register(Trigger)
    class TriggerAdmin(admin.ModelAdmin):
        form = TriggerForm