2010-11-08 1 views
11

У меня есть эти модели (я ограничил число полей только те, которые необходимы)В django, как ограничить выбор иностранного поля на основе другого поля в той же модели?

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, но все равно не пойду за мной.

EDIT 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) 

Но это не работает (на самом деле я пробовал много вариантов, да я Джанго новичок)

ответ

3

Вашего 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) 

(Просто написал их на лету, без тестирования, поэтому нет гарантии, что они не будут работать, но это должно быть близко.)

+0

Привет Eternicode, спасибо, что нашли время на мою проблему. Но у меня есть вопрос, является ли этот код вашей динамикой, потому что мне кажется, что когда я хочу создать location_unit, __init__ уже запущен и не будет запущен снова, независимо от того, какой проект я выбираю. Чтобы сначала выбрать проект, а затем сохранить, а затем снова ввести location_unit, чтобы снова запустить __init__, и сначала единицы покажут только те, которые принадлежат указанному проекту. Правильно ли я это понял? – Brian

+0

Может быть, что-то вроде этого можно использовать: http://stackoverflow.com/questions/3750097/how-to-read-write-input-fields-in-django-admin-tabular-inlines-using-ajax, но у меня нет идея, как реализовать это в admin – Brian

+3

Хорошо, это делает именно то, что я хочу :) https://github.com/digi604/django-smart-selects – Brian