Скажем, у меня есть следующее в моем models.py
:
class Company(models.Model):
name = ...
class Rate(models.Model):
company = models.ForeignKey(Company)
name = ...
class Client(models.Model):
name = ...
company = models.ForeignKey(Company)
base_rate = models.ForeignKey(Rate)
Т.е. есть несколько Companies
, каждый из которых имеет диапазон Rates
и Clients
. У каждого Client
должна быть база Rate
, выбранная из родительского Company's Rates
, а не другого Company's Rates
.
При создании формы для добавления Client
я хотел бы удалить Company
варианты (которые уже были выбраны с помощью кнопки «Добавить клиента» на Company
странице) и также ограничить Rate
варианты выбора Company
.
Как мне сделать это в Django 1.0?
Мой текущий forms.py
файл просто шаблонный на данный момент:
from models import *
from django.forms import ModelForm
class ClientForm(ModelForm):
class Meta:
model = Client
И views.py
это также является основным:
from django.shortcuts import render_to_response, get_object_or_404
from models import *
from forms import *
def addclient(request, company_id):
the_company = get_object_or_404(Company, id=company_id)
if request.POST:
form = ClientForm(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect(the_company.get_clients_url())
else:
form = ClientForm()
return render_to_response('addclient.html', {'form': form, 'the_company':the_company})
В Django 0.96 я смог взломать это, выполнив что-то вроде следующего перед рендерингом шаблона:
manipulator.fields[0].choices = [(r.id,r.name) for r in Rate.objects.filter(company_id=the_company.id)]
ForeignKey.limit_choices_to
кажется многообещающим, но я не знаю, как пройти, the_company.id
и я не уверен , будет ли это работать вне интерфейса администратора в любом случае.
Спасибо. (Это похоже на довольно простой запрос, но если мне нужно что-то изменить, я открыт для предложений.)
Ответы:
ForeignKey представлен django.forms.ModelChoiceField, который является ChoiceField, чьи выборы являются моделью QuerySet. Смотрите ссылку для ModelChoiceField .
Итак, предоставьте QuerySet для
queryset
атрибута поля . Зависит от того, как строится ваша форма. Если вы создадите явную форму, у вас будут поля с именами напрямую.Если вы берете объект ModelForm по умолчанию,
form.fields["rate"].queryset = ...
Это сделано явно в представлении. Нет взлома вокруг.
источник
__init__
методе формы ?В дополнение к ответу С. Лотта и упоминанию в комментариях Гуру, можно добавить фильтры набора запросов, переопределив
ModelForm.__init__
функцию. (Это может быть легко применимо к обычным формам), это может помочь с повторным использованием и поддерживает функцию представления в чистоте.Это может быть полезно для повторного использования, например, если у вас есть общие фильтры, необходимые для многих моделей (обычно я объявляю абстрактный класс Form). Например
Кроме этого, я просто перевожу материал блога Django, из которого есть много хороших.
источник
Это просто и работает с Django 1.4:
Вам не нужно указывать это в классе формы, но вы можете сделать это непосредственно в ModelAdmin, так как Django уже включает этот встроенный метод в ModelAdmin (из документации):
Еще более изящный способ сделать это (например, создать интерфейсный интерфейс администратора, к которому могут обращаться пользователи) - создать подкласс ModelAdmin и затем изменить методы, указанные ниже. Конечным результатом является пользовательский интерфейс, который показывает ТОЛЬКО контент, связанный с ними, позволяя вам (суперпользователю) видеть все.
Я переопределил четыре метода, первые два не позволяют пользователю что-либо удалить, а также удаляют кнопки удаления с сайта администратора.
Третье переопределение фильтрует любой запрос, который содержит ссылку (в примере «пользователь» или «дикобраз» (просто в качестве иллюстрации).
Последнее переопределение фильтрует любое поле внешнего ключа в модели, чтобы отфильтровать доступные варианты, такие же, как и базовый набор запросов.
Таким образом, вы можете представить простой в управлении фронтальный сайт администратора, который позволяет пользователям связываться с их собственными объектами, и вам не нужно вводить конкретные фильтры ModelAdmin, о которых мы говорили выше.
удалить кнопки «удалить»:
предотвращает удаление разрешения
Фильтрует объекты, которые можно просмотреть на сайте администратора:
Фильтрует выбор для всех полей Foreignkey на сайте администратора:
источник
Для этого используется общий вид, например CreateView ...
самая важная часть этого ...
, Прочитать мой пост здесь
источник
Если вы еще не создали форму и хотите изменить набор запросов, вы можете сделать следующее:
Это очень полезно, когда вы используете общие представления!
источник
Итак, я действительно пытался понять это, но кажется, что Джанго все еще не делает это очень простым. Я не настолько глуп, но просто не вижу ни одного (несколько) простого решения.
Я нахожу довольно уродливым переопределение представлений Admin для такого рода вещей, и каждый найденный мной пример никогда полностью не применим к представлениям Admin.
Это настолько распространенное обстоятельство, с моделями, которые я делаю, что я нахожу ужасным, что нет очевидного решения этого ...
У меня есть эти классы:
Это создает проблему при настройке Администратора для Компании, поскольку в нем есть встроенные строки для Контракта и Местоположения, а параметры Контейнера в м2м для Местоположения не фильтруются должным образом в соответствии с Компанией, которую вы в настоящее время редактируете.
Короче говоря, мне понадобится опция администратора, чтобы сделать что-то вроде этого:
В конечном счете, мне было бы все равно, был ли процесс фильтрации размещен в базе CompanyAdmin или в ContractInline. (Размещение его в строке имеет больше смысла, но затрудняет ссылаться на базовый контракт как на «себя».)
Есть ли кто-нибудь, кто знает что-то столь же простое, как этот крайне необходимый ярлык? Когда я делал PHP администраторов для такого рода вещей, это считалось основной функциональностью! На самом деле, он всегда был автоматическим и должен был быть отключен, если вы действительно этого не хотели!
источник
Более публичным способом является вызов get_form в классах Admin. Это также работает для полей без базы данных. Например, здесь у меня есть поле с именем «_terminal_list» в форме, которое можно использовать в особых случаях для выбора нескольких конечных элементов из get_list (запрос), а затем фильтрации на основе request.user:
источник