Django Admin Model ArrayField Change Delimiter
Asked Answered
C

2

5

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.

Caenogenesis answered 16/7, 2017 at 21:49 Comment(2)
I'm not sure I'd consider this a duplicate, but it may point you in the right direction: #31426510Metatherian
that question is a superset of mine.Caenogenesis
C
9

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
Clubfoot answered 16/7, 2017 at 22:38 Comment(0)
C
4

Slightly cleaner solution (without overriding the __init__ in the Form class) would be to just specify the field on the form.

from django.contrib.postgres.forms import SimpleArrayField
from django import forms
from django.forms.fields import CharField
from django.forms.widgets import Textarea

class TriggerForm(forms.ModelForm):
    solutions = SimpleArrayField(CharField(), delimiter='|', widget=Textarea())

This way you can easily choose to go with, for example SplitArrayField or specify different widget for the field.

Croy answered 27/1, 2019 at 11:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.