2014-12-12 3 views
0

Я генерирую некоторый код шаблона Django на лету, чтобы отображать строки в таблицах, которые не хранятся в базе данных Django и не имеют моделей. Я знаю базу данных, и я могу их интроспектировать, если это необходимо, но я не хочу, чтобы написал код вручную.Шаблоны исключений NoReverseMatch, за пределами моделей

Например, поле PSOPRDEFN.OPRCLASS хранит дополнительной ссылки на конкретную строку, где PSCLASSDEFN.OPRID = PSOPRDEFN.OPRCLASS, по существу внешнего ключа. Если нет отношения PSOPRDEFN.OPRCLASS имеет один символ пробела.

У меня также есть страница для данной PSCLASSDEFN строки, где URL является:

url(r'^(?i)permissions/(?P<CLASSID>[A-Z0-9_&]{1,50})/$', 
'pssecurity.views.psclassdefn_detail', 
name="psclassdefn_detail"), 

Обратите внимание, что P CLASSID регулярное выражение не учитывает пробелы, что соответствует сохраняется в таблице PSCLASSDEFN - Я полагаю, что безопаснее ограничивать то, что пользователь может указать в запросе url.

Обратно к моему сгенерированному шаблону: Я хочу связать гиперссылку, если она существует. Я кормлю доморощенным шаблон генератором JSON «директива» указует на то, что я хочу поместить в шаблон (спасибо за вдохновение, Джанго-tables2):

.... 
    { 
     "colname": "LANGUAGE_CD" 
    }, 
    { 
     "urlname": "security:psclassdefn_detail", 
     "colname": "OPRCLASS", 
     "kwargs": [ 
      { 
       "colname": "dbr", 
       "accessor": "dbr" 
      }, 
      { 
       "colname": "CLASSID", 
       "accessor": "inst.OPRCLASS" 
      } 
     ] 
    }, 
    ... 

Некоторой довольно тривиальная генерация коды, то приводит к:

<div class="row"> 
    <div class="col-xs-6 fieldlabel" title="LANGUAGE_CD" >Language Code</div> 
    <div class="col-xs-6 fieldvalue text-left _fv_LANGUAGE_CD">{{inst.LANGUAGE_CD}}</div> 
</div> 

<div class="row"> 
    <div class="col-xs-6 fieldlabel" title="OPRCLASS" >Primary Permission List</div> 
    <div class="col-xs-6 fieldvalue _fv_OPRCLASS"> 
     {% if inst.OPRCLASS|slugify %} 
     <a href="{% url 'security:psclassdefn_detail' dbr=dbr CLASSID=inst.OPRCLASS %}">{{inst.OPRCLASS}}</a> 
     {% endif %} 
    </div> 
</div> 

Моя проблема заключается в том, что начали получать ошибки разрешения URL случайного шаблона при отображении некоторых данных PSOPRDEFN. В конце концов я отследил его до пустых полей OPRCLASS в некоторых строках.

Для того, чтобы избежать этого я первый добавил

{% if inst.OPRCLASS %} 
<a ...></a> 
{% endif %} 

Это не сработало, потому что поле не пусто, то пусто (и, следовательно, не соответствует Classid регулярного выражения). Итак, я снова прочитал документы с фильтрами и обнаружил, что slugify выдает пробелы и не-альфы.

{% if inst.OPRCLASS | slugify %} 
<a ...></a> 
{% endif %} 

Работы, как обходной путь. Проблема в том, что CLASSID хранит только буквенно-цифровой алфавит, но это не всегда верно для других полей. Я бы не прочь исследовать определение столбца таблицы во время исполнения шаблона, чтобы увидеть, что делать, но мне нужно найти подходящий способ отключить разворот URL, только для некоторых строк.

Вопросы. Есть ли лучший фильтр, например, полоса? Полагаю, я всегда мог создать собственный фильтр.

Еще лучше, есть ли тег для выборочного исключения исключений NoReverseMatch'а при создании шаблона?

{% try NoReverseMatch %} 
     <a href="{% url 'security:psclassdefn_detail' dbr=dbr CLASSID=inst.OPRCLASS %}">{{inst.OPRCLASS}}</a> 
{% endtry %} 

Причина, по которой я был настолько подробным в своем описании, состоит в том, что это не то, что можно использовать с использованием моделей. И я не могу настраивать шаблон вручную. Я нахожу, что Django работает очень хорошо без моделей в большинстве случаев, но изменение URL в шаблонах может быть довольно хрупким, когда несколько строк данных не соответствуют ожиданиям. Упрочнение было бы очень полезно.

ответ

1

Вы можете присвоить результат тега url переменной.

{% url 'path.to.view' arg arg2 as the_url %} 
{% if the_url %} 
<a href="{{ the_url }}">link</a> 
{% else %} 
No link 
{% endif %} 

Этот синтаксис не вызывает исключения, если реверсирование представления не выполняется.

+0

Работы по моему сценарию тестирования. Благодаря! –

+0

обновление. Это работает, большую часть времени. Но ** the_url ** присваивается пространству имен общего контекста. Это означает, что при следующем прохождении, если URL-адрес не разрешен, ** the_url ** не присваивается, но предыдущее успешное разрешение доступно для текущего прохода. т. е. вы можете получить последний рассчитанный URL по ошибке. Я попытался присвоить его текущей строке, как в ** как row.the_url **, но это не сработало. –

+0

Хм. Возможно, Django следует изменить так, чтобы тэг url задавал 'the_url'' None' в контексте, если он не смог отменить URL-адрес. Обходной способ может заключаться в том, чтобы обернуть код с помощью инструкции [with] (https://docs.djangoproject.com/en/1.8/ref/templates/builtins/#with), то есть '{% with the_url = ''% } '. – Alasdair

Смежные вопросы