LINUX.ORG.RU

Валидация данных в форме по модели для другой модели

 ,


0

3

Добрый день. Весь не относящийся к делу код я выкинула. У меня есть модель:

class Tag(models.Model):
    name = models.CharField(unique=True, max_length=16, validators=[constants.validator_form_tag_name])

class Server(models.Model):
    tags = models.ManyToManyField(Tag)

Я решила описать форму для создания и редактирования сервера таким образом чтобы пользователь редактировал строку вида «tag1, tag2»:

class ServerCreationForm(forms.ModelForm):
    tags = forms.CharField(label=_('Tags'), required=False)

class Meta:
    model = Server

def __init__(self, *args, **kwargs):
    super(ServerCreationForm, self).__init__(*args, **kwargs)
    if 'instance' in kwargs:
        server = kwargs['instance']
        tags = ''
        for tag in server.tags.all():
            tags += tag.name + ', '
        self.fields['tags'].initial = tags[0:-2]

def clean_tags(self):
    data = self.cleaned_data['tags']
    tag_titles = re.split('\s*,\s*', data)
    for tag_name in tag_titles:
        ???
        raise forms.ValidationError(_('Tag "%s" is too long.') % (tag_name))
    return data

def save(self, commit=True):
    instance = forms.ModelForm.save(self, False)
    old_save_m2m = self.save_m2m

    def save_m2m():
        old_save_m2m()
        instance.tags.clear()

        tag_titles = re.split('\s*,\s*', self.cleaned_data['tags'])

        tags = {}
        for tag in Tag.objects.filter(name__in=tag_titles):
            tags[tag.name] = tag

        for tag_title in tag_titles:
            if tag_title != "":
                if tag_title in tags:
                    tag = tags[tag_title]
                else:
                    tag = Tag(name=tag_title)
                    if commit:
                        tag.save()
                instance.tags.add(tag)

    self.save_m2m = save_m2m

    if commit:
        instance.save()
        self.save_m2m()

    return instance

Все работает как надо за исключением валидации данных (clean_tags - ???). Каким образом я могу провести валидацию каждого тега в соответствии с валидаторами из модели Tag с генерированием соответствующих же исключений?


Ответ на: комментарий от Dmit3Y

Tag._meta.get_field('name').run_validators(tag_name)

Это что за магия?! Оно работает! Спасибо большое!

totik
() автор топика
Ответ на: комментарий от Deleted

Однако документация допускает такое использование.

Поля, начинающиеся с _, считаются приватными.

Считаются, но их использование при необходимости никто не запрещает. Есть еще __ и всякие другие особенности таких полей, но сейчас это не важно.

Dmit3Y
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.