1. redbaron

    15.01.2009

    0 ↑
    0 ↓
    Добрый день. Столкнулся с такой интересно проблемой. Во время валидации делаю raise ValidationError(some_object), но когда пытаюсь отобразить в шаблоне, там в form.errors уже все ввиде строк. Поискал по коду django, так и не нашел где эта замена идет, например, в full_clean методе BaseForm в _errors заносится как раз, то что нужно:
    self._errors[name] = e.messages
    куда копать ума не приложу =(
  2. Иван Сагалаев

    15.01.2009

    0 ↑
    0 ↓

    form.errors — это объект ErrorDict, у которого метод __unicode__ как раз такой, чтобы в HTML списком выводить.

    Если нужно по нему пробежаться в Питоне, то стандартно:

    for field, error_list in form.errors.items():
        # ...
    

    Если нужно в шаблоне получить список ошибок одного поля, то само поле умеет вынимать свои ошибки из формы:

    {% for error in form.field_name.errors %}
    
  3. redbaron

    15.01.2009

    0 ↑
    0 ↓
    Именно так я и делаю (через .items() ),можете сами попробовать, там волшебным образом уже строки оказываются,хотя сохранял объекты.
  4. Иван Сагалаев

    15.01.2009

    0 ↑
    0 ↓

    Тогда я не понимаю вопроса :-).

    Вот здесь:

    for field, error_list in form.errors.items():
        # ...
    

    error_listы внутри цикла будут списками строк. А вам что хочется получить?

  5. redbaron

    15.01.2009

    0 ↑
    0 ↓
    Объекты, которые передавал в ValidationError при создании, а не их строковое представление.
  6. Иван Сагалаев

    15.01.2009

    0 ↑
    0 ↓

    А... Не, так не получится. ValidationError — это сообщение об ошибке, там все явно приводится к строкам, и хранить дополнительные объекты там нельзя. Теоретически можно отнаследоваться от ValidationError и хранить там все что угодно, но вот зачем бы это было надо, я как-то не представляю. Опишите usecase, может придумаем другой способ.

  7. redbaron

    16.01.2009

    0 ↑
    0 ↓
    Да уж, видимо так и есть :)
    Делаю сайт обмена скинами для игры Live For Speed, имя скина должно быть уникальным, хочется показать пользователю ссылку на существующий скин, если он заливает с тем же именем. Мол смотри вот уже есть такой. Думал передам объект, а там через x.get_absolute_url и x.name покажу нормальную ссылку. Не вышло :)

    В итоге сделал как, сообщение об ошибке начал с маркера "!" и далее "поля" для сообщения - уже текстовый URL и текстовое имя. В шаблоне вывода ошибок детекчу все ошибки начинающиеся с "!" и прогоняю их через простенький фильтр выдирающий нужные поля.
  8. А почему бы не сформировать уже готовый html снипет и передать его в ValidationError, а потом пусть себе выводится как обычно.

  9. Иван Сагалаев

    16.01.2009

    0 ↑
    0 ↓

    А почему бы не сформировать уже готовый html снипет и передать его в ValidationError

    +1

  10. redbaron

    16.01.2009

    0 ↑
    0 ↓
    Думал об этом,решил отказаться, т.к. хочу задавать способ отображения ошибок в одном месте, а не бегать при случае по коду выискивая, что,где и как передается.
  11. Думал об этом,решил отказаться, т.к. хочу задавать способ отображения ошибок в одном месте, а не бегать при случае по коду выискивая, что,где и как передается.

    Заведите функцию в "одном месте".

  12. redbaron

    16.01.2009

    0 ↑
    0 ↓
    Проблема решена, решение меня полностью устраивает, смысл дальше обсуждать?
  13. Grigory Fateyev

    16.01.2009

    0 ↑
    0 ↓
    Расскажите нам к решили?
  14. Проблема решена, решение меня полностью устраивает, смысл дальше обсуждать?

    Эй, ну рот то нам не надо затыкать! Решение ваше явно кривое, вот мы дальше и рассуждаем. Не хотите, то не читайте.

  15. Иван Сагалаев

    16.01.2009

    0 ↑
    0 ↓

    Я, если честно, не вижу никакого затыкания рта. Давайте не будем все ругаться.

    А кривое ли решение — это всегда вопрос обсуждаемый. Да и решение redbaron не приводил еще :-)

  16. redbaron

    19.01.2009

    0 ↑
    0 ↓
    Как не приводил? Описал же выше:)
    Делаю сначала что то вроде ValidationError(make_string(data1,data2,data3))

    А потом в шаблоне
    {% if err|is_encoded %}
    <a href={{ err|get_field:"1" }}>{{ err|get_field:"2" }}</a>
    {% else %}
    {{ err }}
    {% endif %}
    Весь код вывода ошибок в виде отдельного файла предназначенного для инклюда.
    Таким образом я при формировании ошибки в сериализую в строку любые нужные мне данные, в строку добавляется маркер по которому рукописный тег is_encoded определяет, что это не простой текст ошибки, ну а далее тег get_field выдирает занесенные ранее данные.

    По-моему получилось вполне в духе django - в шаблон приходят только данные и внешний вид зависит только от шаблона. ИМХО это красивее и удобнее, чем вгонять в ValidationError сразу html код.

    Пока мне понабилось так протаскивать только один набор данных, если понадобится несколько и для каждого предполагается разное отображения, то можно расширить is_encoded до err_type и прогоняя его через case уже формировать разные представления.

Внимание! Это довольно старый топик, посты в него не попадут в новые, и их никто не увидит. Пишите пост, если хотите просто дополнить топик, а чтобы задать новый вопрос — начните новый.