Ответ 1
Это ответ, он блестящий: https://github.com/digi604/django-smart-selects
У меня есть эти модели (я ограничил количество полей только теми, которые вам нужны)
class unit(models.Model):
name = models.CharField(max_length=200)
class project(models.Model):
name = models.CharField(max_length=200)
class location(address):
project = models.ForeignKey(project)
class project_unit(models.Model):
project = models.ForeignKey(project)
unit = models.ForeignKey(unit)
class location_unit(models.Model):
project = models.ForeignKey(project)
#Limit the selection of locations based on which project has been selected
location = models.ForeignKey(location)
#The same here for unit. But I have no idea how.
unit = models.ForeignKey(project_unit)
Моя голова-новичок просто не может понять, как ограничить два поля, местоположение и блок, в модели location_unit, чтобы отображать только те варианты, которые относятся к выбранному проекту в location_unit. Должен ли я переопределить форму модели и сделать запрос там, или я могу использовать limit_choices_to. В любом случае я не смог выполнить оба
Изменить: просто чтобы уточнить, я хочу, чтобы это произошло в Django Admin. Я также попробовал formfield_for_foreignkey, но все равно не пойду за мной.
ИЗМЕНИТЬ 2:
def formfield_for_foreignkey(self, db_field, request, **kwargs):
if db_field.name == "unit":
kwargs["queryset"] = project_unit.objects.filter(project=1)
return db_field.formfield(**kwargs)
return super(location_unit_admin, self).formfield_for_foreignkey(db_field, request, **kwargs)
Вышеприведенный фрагмент кода работает. Но, конечно, я не хочу, чтобы проект указывал на 1. Как я могу ссылаться на модели project_id? Я пробовал это:
kwargs["queryset"] = project_unit.objects.filter(project=self.model.project.project_id)
Но это не работает (на самом деле я пробовал много вариаций, да, я новичок в django)
Это ответ, он блестящий: https://github.com/digi604/django-smart-selects
Ваш formfield_for_foreignkey
выглядит так, как будто это может быть хорошим направлением, но вы должны понимать, что ModelAdmin (self
) не даст вам конкретного экземпляра. Вы должны получить это из request
(возможно, сочетание django.core.urlresolvers.resolve
и request.path
)
Если вы хотите использовать эту функцию только в админе (а не в валидации модели вообще), вы можете использовать пользовательскую форму с классом администратора модели:
forms.py:
from django import forms
from models import location_unit, location, project_unit
class LocationUnitForm(forms.ModelForm):
class Meta:
model = location_unit
def __init__(self, *args, **kwargs):
inst = kwargs.get('instance')
super(LocationUnitForm, self).__init__(*args, **kwargs)
if inst:
self.fields['location'].queryset = location.objects.filter(project=inst.project)
self.fields['unit'].queryset = project_unit.objects.filter(project=inst.project)
admin.py:
from django.contrib import admin
from models import location_unit
from forms import LocationUnitForm
class LocationUnitAdmin(admin.ModelAdmin):
form = LocationUnitForm
admin.site.register(location_unit, LocationUnitAdmin)
(Просто написал их "на лету" без тестирования, поэтому не гарантируйте, что они будут работать, но они должны быть близки.)