django widget queryset not updating

泪湿孤枕 提交于 2021-02-19 05:58:06

问题


I have a custom django widget to replace the standard ModelChoiceField widget.

class SelectModelWidget(forms.TextInput):
    """
    @Usage: field = ModelChoiceField(queryset=Model.objects.all(),
                                     widget=SelectModelWidget(attrs={}))
    """

    def __init__(self, attrs=None, title=None,
                 template="widgets/select_widget.html"):
        super(SelectModelWidget, self).__init__(attrs)
        self.template = template
        self.title = title

    def render(self, name, value, attrs=None):
        if value is None: value = ''

        # TODO: the queryset does not update
        # Set the title for the selection page, use model name as default
        model_queryset = self.choices.queryset
        if model_queryset is not None and self.title is None:
            self.title = model_queryset.model._meta.verbose_name.title()

        # Get the currently selected instance if it exists
        try:
            instance = model_queryset.get(pk=value)
            text = instance
        except (ValueError, model_queryset.model.DoesNotExist):
            text = ''

        form_id = attrs.pop("id")
        widget_template = loader.get_template(self.template)
        context = Context({
                           "attrs": attrs,
                           "id": form_id,
                           "name": name,
                           "value": value,
                           "text": text,
                           "title": self.title,
                           "queryset": model_queryset,
                          })

        return widget_template.render(context)

The issue appears to be around this area:

    model_queryset = self.choices.queryset
    if model_queryset is not None and self.title is None:
        self.title = model_queryset.model._meta.verbose_name.title()

the self.choices.queryset line should get the queryset that was passed to the ModelChoiceField, and I think I lack an understanding of how it is initialised, because when I load up the page for the first time the Model queryset populates fine, however if I add a new instance of that model and reload the page, the queryset doesn't update to include the new instance. And I have to restart the server in order to get the new instance to appear in the list. Is there any reason as to why the queryset would only be initialised once and never updated?

Edit: To add, I'm convinced it's the widget code because when I remove the widget from the form and use the default widget (not sure which that is) it works flawlessly and as I would expect it to. I just can't work out why the model_queryset variable is never updating with the new queryset.

the form code that relates to this widget in my project is literally just:

address = forms.ModelChoiceField(queryset=models.Address.objects.all(),
                             widget=widgets.SelectModelWidget())

回答1:


self.choices.queryset.all() should work.




回答2:


In the end I decided that I did not need access to the queryset itself, so rather than self.choices.queryset, I am just using self.choices (and removing the blank choice that is put in by default by modelchoicefields).

That solved my immediate problem but I would still be interested to know why self.choices.queryset behaves differently to self.choices. Whether it's a bug or a feature I do not understand is unclear.




回答3:


I think problem is somewhere in caching of a rendered template or a queryset. But instead of dealing with that, I would recommend, using a great package: django-crispy-forms, which allows you to customize any field using django's templating engine. After numerous attempts trying to customize widgets rendering in django, that was the best solution I could find, turned out to be a fairly simple one too.



来源:https://stackoverflow.com/questions/14672407/django-widget-queryset-not-updating

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!