2015-07-15 26 views
12

ArrayField'ın yönetici widget'ının nesneleri eklemeye ve silmeye izin vermesinin bir yolu var mı? Varsayılan olarak, bunun yerine sadece bir metin alanı görüntülenir ve değerleri için virgül ayırma kullanır.Better ArrayField yönetici aracı?

Uygunsuz davranmanın yanı sıra, dizinin taban alanının bir Char/TextField olması durumunda AFAICT, dizideki metinlerin herhangi birinde virgül eklemenin herhangi bir yoluna izin vermez. OP, ya da orada herkes seyir için

cevap

1

django-select2ArrayField işlemek için bir yol sunar Select2 kullanıyor. Onların belgelerinde, örneğin ArrayField içindir:

http://django-select2.readthedocs.io/en/latest/django_select2.html#django_select2.forms.Select2TagWidget

zaten seçili değerlerini işlemek için:

class ArrayFieldWidget(Select2TagWidget): 

    def render_options(self, *args, **kwargs): 
     try: 
      selected_choices, = args 
     except ValueError: # Signature contained `choices` prior to Django 1.10 
      choices, selected_choices = args 
     output = ['<option></option>' if not self.is_required and not self.allow_multiple_selected else ''] 
     selected_choices = {force_text(v) for v in selected_choices.split(',')} 
     choices = {(v, v) for v in selected_choices} 
     for option_value, option_label in choices: 
      output.append(self.render_option(selected_choices, option_value, option_label)) 
     return '\n'.join(output) 

    def value_from_datadict(self, data, files, name): 
     values = super().value_from_datadict(data, files, name) 
     return ",".join(values) 

Formunuza widget eklemek için:

class MyForm(ModelForm): 

    class Meta: 
     fields = ['my_array_field'] 
     widgets = { 
      'my_array_field': ArrayFieldWidget 
     } 
6

Attığım Bunun için bir kredi (original source), ancak daha kolay bir seçenek modele ArrayField alt sınıfı için ve varsayılan yönetici widget'ını geçersiz kıl. Temel bir uygulama (Django 1.9 test ve 1.10) aşağıdaki gibidir:

models.py

from django import forms 
from django.contrib.db import models 
from django.contrib.postgres.fields import ArrayField 


class ChoiceArrayField(ArrayField): 
    """ 
    A field that allows us to store an array of choices. 
    Uses Django's Postgres ArrayField 
    and a MultipleChoiceField for its formfield. 
    """ 

    def formfield(self, **kwargs): 
     defaults = { 
      'form_class': forms.MultipleChoiceField, 
      'choices': self.base_field.choices, 
     } 
     defaults.update(kwargs) 
     # Skip our parent's formfield implementation completely as we don't 
     # care for it. 
     # pylint:disable=bad-super-call 
     return super(ArrayField, self).formfield(**defaults) 


FUNCTION_CHOICES = (
    ('0', 'Planning'), 
    ('1', 'Operation'), 
    ('2', 'Reporting'), 
) 

class FunctionModel(models.Model): 
    name = models.CharField(max_length=128, unique=True) 
    function = ChoiceArrayField(
     base_field=models.CharField(max_length=256, choices=FUNCTION_CHOICES), 
     default=list) 
+0

Eksik bir şey? Varsayılan yönetici widget'ını gerçekten nerede geçersiz kılıyorsunuz? Weblog'dan alıntıladığınız alıntı, oldukça sınırlı ArrayField'ı faydalı bir işe dönüştürür ve çok iyi çalışır. Ancak, bulduğunuz yönetici widget'inin en iyi şekilde kullanılmasını görmek güzel olurdu. Select2'ye bir şeyler verebilirim. – Marakai

+2

Daha eksiksiz olması için örneği genişlettim. – ropable