Search code examples
djangodjango-widget

Replacement for django `render_options`


So I am implementing this answer: Country/State/City dropdown menus inside the Django admin inline, but the def render piece of code needs to be redone.... I have managed to redo it, but I am struggling to find a replacement (or the correct code) for the self.render_options method (which was deprecated on 1.11) of the Widget class.

I am on Django 2.1. What should I change? Here is my code:

class StateChoiceWidget(widgets.Select):
    def render(self, name, value, attrs=None, renderer=None):
        self.choices = [(u"", u"---------")]
        if value is None:
            value = ''
            model_obj = self.form_instance.instance
            if model_obj and model_obj.country:
                for m in model_obj.country.state_set.all():
                    self.choices.append((m.id, smart_text(m)))
        else: 
            obj = State.objects.get(id=value)
            for m in State.objects.filter(country=obj.country):
                self.choices.append((m.id, smart_text(m)))

        final_attrs = self.build_attrs(attrs)
        output = ['<select%s>' % flatatt(final_attrs)]
        for option in self.choices:
            output.append('<option value="%s">%s</option>' % (option[0], option[1]))
        output.append('</select>')
        return mark_safe(''.join(output))

Original poster updated the sample code, so now it doesn't show the code in the question: see previous revision https://stackoverflow.com/revisions/52174508/1


Solution

  • So I figured out the answer. Will post it here in case someone runs into the same issue.

    class StateChoiceWidget(widgets.Select):
        def render(self, name, value, attrs=None, renderer=None):
            self.choices = [(u"", u"---------")]
            if value is None or value == '':
                value = ''
                model_obj = self.form_instance.instance
                if model_obj and model_obj.country:
                    for m in model_obj.country.state_set.all():
                        self.choices.append((m.id, smart_text(m)))
            else: 
                obj = State.objects.get(id=value)
                for m in State.objects.filter(country=obj.country):
                    self.choices.append((m.id, smart_text(m)))
    
            final_attrs = self.build_attrs(attrs) 
    
            s = widgets.Select(choices=self.choices)
            select_html = s.render(name=name,value=value,attrs=attrs)
    
            return mark_safe(''.join(select_html))