Джанго. Отфильтровать новую запись в строке с данными на основе родительского ПК

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

Модель Тема принадлежит курсу.

class Theme (models.Model):
    id = models.AutoField(primary_key=True) # AutoField?
    code = models.CharField(max_length=5)
    course = models.ForeignKey(Course)
    theme_text = models.CharField(max_length=50)
    description = models.TextField(blank=True, max_length=1000)
    zorder = models.IntegerField()

Индикаторная модель также относится к курсу

class Indicator (models.Model):
    id = models.AutoField(primary_key=True) # AutoField?
    code = models.CharField(max_length=10)
    indicator_text = models.TextField(blank=True)
    explained = models.TextField("Explained",blank=True)
    course = models.ForeignKey('curriculum.Course')
    theme = models.ForeignKey(Theme)        
    strand = models.ForeignKey(Strand,blank=True,null=True)
    level = models.ForeignKey(Level,blank=True,null=True)
    concept = models.ManyToManyField(Concept,blank=True)

Форма темы администратора вызывает встроенный индикатор.

class ThemeAdmin(admin.ModelAdmin):
    list_display = ['code', 'theme_text','description','course']
    list_filter = ['course']
    inlines = [InlineIndicator]

который, в свою очередь, вызывает IndicatorInlineForm

class InlineIndicator(admin.TabularInline):
    form = IndicatorInlineForm
    model = Indicator
    extra = 0

IndicatorInlineForm фильтрует данные по некоторым полям (курс, тема, цепочка и концепция)

class IndicatorInlineForm (forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(IndicatorInlineForm, self).__init__(*args, **kwargs)
        if self.instance.pk is not None:
            self.fields['course'].queryset = Course.objects.filter(id=self.instance.course)
            self.fields['theme'].queryset = Theme.objects.filter(course=self.instance.course)
            self.fields['strand'].queryset = Strand.objects.filter(course=self.instance.course)
            self.fields['concept'].queryset = Concept.objects.filter(course=self.instance.course)
        else:
            self.fields['course'].queryset = Course.objects.filter(id=4)
            self.fields['theme'].queryset = Theme.objects.filter(course=4)
            self.fields['strand'].queryset = Strand.objects.filter(course=4)
            self.fields['concept'].queryset = Concept.objects.filter(course=4)

Это работает для существующих записей, где идентификатор курса был установлен в записи индикатора, но еще не работает для новых записей индикатора.

Я хотел бы, чтобы новые записи индикаторов использовали курс course.id в соответствии с темой для фильтрации доступных параметров.

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

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

Спасибо в ожидании вашей помощи (и всей помощи до сих пор).

Крис


person Davies-Barnard    schedule 09.11.2015    source источник
comment
что такое «родитель»? это всегда один и тот же объект?   -  person Sander van Leeuwen    schedule 09.11.2015
comment
Привет, родитель всегда будет экземпляром типа курса. Я временно жестко запрограммировал его как 4 в качестве доказательства, что форма фильтруется нормально, но она должна автоматически получать ее из формы идентификатора родительского курса.   -  person Davies-Barnard    schedule 09.11.2015
comment


Ответы (1)


Я смог ответить на этот вопрос с помощью formfield-for-foreignkey-and-inline-admin хотя, похоже, это не работает для концепции manytomany field.

    def formfield_for_foreignkey(self, db_field, request=None, **kwargs):
    changelist_filters = request.GET['_changelist_filters'].rsplit("=",1)
    course_id = int(changelist_filters[1])

    if db_field.name == 'course':
        kwargs['queryset'] = Course.objects.filter(pk = course_id)
    elif db_field.name == 'strand':
            kwargs['queryset'] = Strand.objects.filter(course = course_id)
    elif db_field.name == 'concept':
            kwargs['queryset'] = Concept.objects.filter(course = course_id)

    return super(InlineIndicator, self).formfield_for_foreignkey(db_field, request, **kwargs)   

Я удалил фильтры из IndicatorInlineForm, поскольку они больше не нужны.

person Davies-Barnard    schedule 10.11.2015