Django: MultiValueField и MultiWidget - PullRequest
6 голосов
/ 19 мая 2011

В документации Django не очень подробно объясняется, как использовать MultiValueField и MultiWidget. Я пытался проанализировать одну реализацию и не дал хороших результатов. Не возражает ли кто-нибудь дать мне быстрый указатель в правильном направлении?

Мой пример:

widgets.py

from django import forms

class TestMultiWidget(forms.MultiWidget):

    def __init__(self, attrs=None):
        widgets = (
            forms.TextInput(attrs=attrs),
            forms.TextInput(attrs=attrs),
        )
        super(TestMultiWidget, self).__init__(widgets, attrs)

    def decompress(self, value):
        if value:
            return value.split(':::')[0:2]
        return ['', '']

fields.py

from django import forms
from widgets import TestMultiWidget

class TestMultiField(forms.MultiValueField):
    widget = TestMultiWidget

    def __init__(self, *args, **kwargs):
        fields = (
            forms.CharField(),
            forms.CharField(),
        )
        super(TestMultiField, self).__init__(fields, *args, **kwargs)

    def compress(self, data_list):
        if data_list:
            return ':::'.join(data_list)
        return ''

models.py

from django.db import models
from util.fields import TestMultiField

class Test(models.Model):
    a = models.CharField(max_length=128)
    b = TestMultiField()
    c = models.CharField(max_length=128)

admin.py

from django.contrib import admin
from models import Test
admin.site.register(Test)

И Полученный админ .

Кто-нибудь знает, что здесь происходит? Я предполагаю, что происходит непреднамеренное подавление исключений, но я не смог найти источник.

Спасибо!

1 Ответ

15 голосов
/ 15 июня 2011

Обратите внимание, что django.forms.MultiValueField является полем формы , а не полем модели (например, django.db.models.CharField). Поэтому оно не рассматривается как поле модели в вашей тестовой модели и не было создано в вашей базе данных. (Вы можете проверить это с помощью ./manage.py sqlall myapp).

Измените файл models.py на:

from django.db import models
from fields import TestMultiField

class TestMultiModelField(models.Field):

    def formfield(self, **kwargs):
        defaults = {'form_class': TestMultiField}
        defaults.update(kwargs)
        return super(TestMultiModelField, self).formfield(**defaults)

    def get_internal_type(self):
        return 'TextField'        

class Test(models.Model):
    a = models.CharField(max_length=128)
    b = TestMultiModelField()
    c = models.CharField(max_length=128)      

удалите свою таблицу (в linux / mac: ./manage.py sqlclear myapp | ./manage.py dbshell) и syncdb, чтобы создать вашу таблицу, на этот раз со столбцом b. Проверьте своего администратора сейчас.

Пояснение: Чтобы создать настраиваемое поле модели, выполните следующие действия: https://docs.djangoproject.com/en/dev/howto/custom-model-fields/

Набор, соответствующий полю модель , соответствующему поле , использовался метод поле формы .

(Кстати, «правильный» способ проектирования поля модели, вероятно, немного отличается, используя to_python и get_prep_value)

...