Здесь есть много отличных ответов, но я хочу затронуть то, о чем я не упоминал: Объектно-ориентированный дизайн посвящен полномочным объектам .
Вы хотите инкапсулировать все свои правила, дополнительную работу и внутренние детали внутри соответствующего объекта. Таким образом, другим объектам, взаимодействующим с этим, не нужно беспокоиться обо всем этом. На самом деле, вы хотите пойти дальше и активно предотвратить другие объекты от обхода этих внутренних элементов.
Когда вы наследуете List
, все остальные объекты могут видеть вас как Список. Они имеют прямой доступ к методам добавления и удаления игроков. И ты потеряешь контроль; например:
Предположим, вы хотите различать, когда игрок уходит, зная, удалены ли они, ушли или уволены. Вы можете реализовать метод RemovePlayer
, который принимает соответствующее перечисление ввода. Однако, наследуя от List
, вы не сможете предотвратить прямой доступ к Remove
, RemoveAll
и даже Clear
. В результате вы фактически лишили вашего класса FootballTeam
.
Дополнительные мысли об инкапсуляции ... Вы подняли следующее беспокойство:
< blockquote>Это делает мой код ненужным подробным. Теперь я должен вызывать my_team.Players.Count, а не только my_team.Count.
blockquote> Вы правы, это было бы излишне подробным для всех клиентов, чтобы использовать вашу команду. Тем не менее, эта проблема очень мала по сравнению с тем фактом, что вы выставили List Players
всем и каждому, чтобы они могли играть с вашей командой без вашего согласия.
Вы продолжаете говорить:
Это просто не имеет никакого смысла. Футбольная команда не имеет «списка» игроков. Это список игроков. Вы не говорите: «Джон Макфуталлер присоединился к игрокам SomeTeam». Вы говорите: «Джон присоединился к SomeTeam».
blockquote>Вы ошибаетесь в первом бит: оставьте слово «список», и на самом деле очевидно, что в команде есть игроки. Тем не менее, вы ударили ноготь по голове вторым. Вы не хотите, чтобы клиенты вызывали
ateam.Players.Add(...)
. Вы действительно хотите, чтобы они набралиateam.AddPlayer(...)
. И ваша реализация (возможно, между прочим) вызоветPlayers.Add(...)
внутренне.
Надеюсь, вы увидите, насколько важна инкапсуляция для цели расширения ваших объектов. Вы хотите, чтобы каждый класс хорошо выполнял свою работу, не опасаясь вмешательства с других объектов.
пользовательский тег шаблона , кажется, решение. Пользовательский фильтр также сделал бы, хотя это может быть менее изящно. Но необходимо было бы отступить к пользовательской форме, представляющей в обоих случаях.
, Если это - задача высокой важности; я создал бы Mixin, который позволяет мне аннотировать поля формы классами маркировки и методами рендеринга формы предоставлений с помощью тех классов. Так, чтобы следующий код работал:
{{ form.as_table_with_label_classes }}
, Но я хотел бы спросить; Вам действительно нужен класс на теге label? Я имею в виду мудрый дизайном HTML. Это абсолютно необходимо для , добавляют класс там? Не мог это быть решенным с некоторым CSS как:
encapsulating_selector label {
some-attr: some-value;
}
я иногда использую jQuery для таких случаев где; это улучшит страницу, если это будет работать, но это не будет бедствие, если это не сделает . И сохраните источник HTML максимально минимизированным.
Я согласен с ответом номер один, с помощью css это можно сделать, но. Каков резонанс для этого в исходном коде django?
В django.forms.forms.py есть это определение, которое показывает, что есть код для отображения атрибутов в ярлыках:
class BoundField(StrAndUnicode):
# ....
def label_tag(self, contents=None, attrs=None):
contents = u'<label for="%s"%s>%s</label>' % (widget.id_for_label(id_), attrs, unicode(contents))
, но _html_output
вызывает эту функцию без attrs:
label = bf.label_tag(label) or ''
Похоже, что django частично подготовлен к этому, но на самом деле он его не использует.
Как насчет добавления класса CSS в поле формы в forms.py, например:
class MyForm(forms.Form):
title = forms.CharField(widget=forms.TextInput(attrs={'class': 'foo'}))
, тогда я просто делаю следующее в шаблоне:
<label for="id_{{form.title.name}}" class="bar">
{{ form.title }}
</label>
Конечно, это может быть легко изменен для работы в теге цикла for в шаблоне.