Note that there are some explanatory texts on larger screens.

plurals
  1. POInstance parameter not being passed in nested inlines form
    primarykey
    data
    text
    <p>I am implementing nested inlines with my 3-tiered model and currently having it functional. However, I can't limit my <code>relevantindicator</code> drop-down choices even though I am passing the correct instance. Currently <code>relevantindicator</code> displays all values in the table in the drop-down selection. I'd like to limit the values to only those associated with the <code>disease</code> instance. Is there a way to do that? </p> <p>I'm using <a href="https://stackoverflow.com/questions/10953548/correct-way-to-save-nested-formsets-in-django">Correct way to save nested formsets in Django</a> and <a href="http://yergler.net/blog/2009/09/27/nested-formsets-with-django/" rel="nofollow noreferrer">http://yergler.net/blog/2009/09/27/nested-formsets-with-django/</a> as references.</p> <p>models.py</p> <pre><code>class Disease(models.Model): disease = models.CharField(max_length=255) class Indicator(models.Model): relevantdisease = models.ForeignKey(Disease) indicator = models.CharField(max_length=255) class IndicatorValue(models.Model): relevantindicator = models.ForeignKey(Indicator) indicator_value = models.CharField(max_length=50) </code></pre> <p>forms.py</p> <pre><code>class BaseIndicatorFormSet(BaseInlineFormSet): def __init__(self, *args, **kwargs): try: instance = kwargs.pop('instance') except KeyError: super(BaseIndicatorFormSet, self).__init__(*args, **kwargs) def save_new(self, form, commit=True): instance = super(BaseIndicatorFormSet, self).save_new(form, commit=commit) form.instance = instance for nested in form.nested: nested.instance = instance for cd in nested.cleaned_data: cd[nested.fk.name]=instance return instance ... def add_fields(self,form,index): super(BaseIndicatorFormSet, self).add_fields(form, index) try: instance = self.get_queryset()[index] pk_value = instance.pk except IndexError: instance=None pk_value = hash(form.prefix) form.nested = [ IndicatorValueFormSet( disease = instance, queryset = IndicatorValue.objects.filter(relevantindicator = pk_value), prefix = 'value_%s' % pk_value)] class BaseIndicatorValueFormSet(BaseModelFormSet): def __init__(self, disease, *args, **kwargs): super(BaseIndicatorValueFormSet, self).__init__(*args, **kwargs) self.disease = disease def save_new(self, form, commit=True): instance = form.save(commit=False) instance.disease = self.disease if commit: instance.save() return instance def save_existing(self, form, instance, commit=True): return self.save_new(form, commit) class IndicatorValueForm(forms.ModelForm): def __init__(self, *args, **kwargs): try: disease_obj = kwargs.pop('disease') except KeyError: super(IndicatorValueForm, self).__init__(*args, **kwargs) return super(IndicatorValueForm, self).__init__(*args, **kwargs) queryset = Indicator.objects.filter(relevantdisease =disease_obj) self.fields['relevantindicator'].queryset = queryset disease_obj = get_object_or_404(Disease, pk=2) #hard-wired CurriedForm = formset_factory(IndicatorValueForm, extra=3) CurriedForm.form = staticmethod(curry(IndicatorValueForm, disease = disease_obj)) IndicatorValueFormSet = inlineformset_factory(Indicator, IndicatorValue, formset=BaseIndicatorValueFormSet, form = CurriedForm, extra=3) IndicatorFormSet = inlineformset_factory(Disease, Indicator, formset=BaseIndicatorFormSet, extra=0) </code></pre> <p>views.py</p> <pre><code> disease = get_object_or_404(Disease, pk=disease_id) if request.method == "POST": formset = IndicatorFormSet(request.POST, instance=disease) if formset.is_valid(): rooms = formset.save_all() return HttpResponseRedirect(reverse('option', kwargs={'disease_id':disease_id})) else: formset = IndicatorFormSet(instance=disease) context = {'disease': disease, 'indicators': formset, 'hide_breadcrumb':hide_breadcrumb} return render_to_response('valdrui.html',context, context_instance=RequestContext(request)) </code></pre> <p>template.html</p> <pre><code> {% if relevantindicator.nested %} {% for formset in relevantindicator.nested %} {{ formset.as_table }} {% endfor %} {% endif %} </code></pre> <p><strong>Update</strong> My feeling is that I need to pass the disease instance from form.nested down to BaseIndicatorValueFormSet. But it does not seem to be working.</p> <p>Screenshots to provide clarity. </p> <p><img src="https://i.stack.imgur.com/QB3Ry.png" alt="relevantindicator provides a drop-down"></p> <p>relevantindicator provides a drop-down</p> <p><img src="https://i.stack.imgur.com/arFaQ.png" alt="When there is a indicator_value, the correct relevantindicator is selected. However, when adding a new indicator_vale, all relevantindicator for all relevantdiseases are available. I&#39;d like to limit the relevantindicator choices to the relevantdiseases (the disease instance)"></p> <p>When there is a indicator_value, the correct relevantindicator is selected. However, when adding a new indicator_value, all relevantindicator for all relevantdiseases are available. I'd like to limit the relevantindicator choices to the relevantdiseases (the disease instance)</p> <p>Update 2: I had to define an <code>instance</code> in BaseIndicatorFormSet under <code>def __init__</code>. I also needed to define the forms in forms.py since <code>BaseIndicatorFormSet</code> calls <code>IndicatorValueFormSet</code>. The instance is currently hard-wired, just to see if the template will render. Unfortunately, the form in the template does not render but also does not produce any errors. I can't figure out why since there is no error produced.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload