【问题标题】:Django: custom content in admin formDjango:管理表单中的自定义内容
【发布时间】:2012-03-26 01:12:07
【问题描述】:

对于我的一个模型,我想在 change_form 中显示额外的内容。基本上,我的模型如下所示:

class News(models.Model):
    ...

class NewsFromSource(models.Model):
    news                    = models.ForeignKey(News)
    ...

我想添加一个“搜索”按钮,单击该按钮会触发对外部新闻源的 Web 服务请求,下拉可用内容,并列出包含的所有新闻。然后,用户可以选择其中一个“附加”到管理界面中当前编辑的新闻(即根据通过网络服务下载的内容创建一个新的 NewsFromSource)。

我已经完成了网络服务。实现搜索按钮、结果列表显示(我有一个可以工作的视图和模板,需要以某种方式将它们放入表单)和保存部分的最佳方法是什么?

【问题讨论】:

    标签: django django-forms django-admin django-widget


    【解决方案1】:
    1. 我们假设您有相关的新闻模型。将该字段添加到我们要破解的模型管理员的 raw_id_fields,然后:

    2. 为此模型重载change_form模板,在admin/yourapp/yourmodel/change_form.html中扩展admin/change_form.html

    3. 在该模板中添加 javascript 到:

      1. 从 raw 的 news raw id 字段中隐藏输入和放大镜图标,你也可以在 css 中做到这一点

      2. 在该表单行中添加类似跨度的按钮样式,当单击它时会打开一个弹出窗口

      3. 它应该打开的弹出窗口应该是您的工作视图/模板,其中包含用于选择新闻的表单

      4. 当用户选择一条新闻时,弹窗应该做一个ajax post请求来获取新闻id,并自行关闭

      5. 该值设置为隐藏的原始 id 字段输入,这很困难但不要害怕有人(声明:我)发布an article with the whole technical details,也发现another one but I didn't test it

    这将是相当多的工作。耐心和毅力将是您完成这项任务的最佳品质 B)

    【讨论】:

    • 对不起,我刚刚发现弹出窗口不能很容易地“返回”json,所以我改变了我的建议
    • 感谢您的反馈,原来我的 hosts 文件被破解了……更新了链接
    • 谢谢。我一定会试试这个,让你知道它是如何工作的。隐藏放大镜图标位似乎有点骇人听闻。没有别的办法吗?
    • 其实我认为这不是我想要的。我想从 News 项开始,在 Internet 上搜索现有新闻,然后使用 ForeignKey News 创建一个新的 NewsSource 项。如果我没记错的话,你描述的方法反过来也行。
    • 在 3.4 点。用户选择了一条新闻,所以是时候保存它了。此外,弹出窗口应在 3.5 点返回新闻的 id。所以一切都是为了完成交易 B)但你最好找到一个更简单的解决方案 - 一个 js 弹出框会更容易。
    【解决方案2】:

    我最终做了以下事情:

    1)

    我创建了一个用于获取搜索结果的视图,归结为:

    #/myproject/admin/views.py
    @never_cache
    def news_search(request):
    
        #...query web service
        if 'q' in request.POST:
            search_term = request.POST['q']
        else:
            search_term = ''
    
        news = NewsSearch()
        news.search(search_term)
    
        return render_to_response(  'news_search_results.html', 
                                {   'q':            search_term,
                                    'news':     news.result_list,
                                    'page':         page,
                                    'page_left':    news.page_left, 
                                    'page_right':   news.page_right}
                                    )  
    

    2) 我映射了视图:

    #/myapp/urls.py
    ...
    url(r'^myapp/news/search/$', views.news_search),
    

    3) 我为新闻模型扩展了 change_form.html,代码如下:

    #/myproject/templates/admin/myapp/news/change_form.html
        {% extends "admin/change_form.html" %}
        {% block after_field_sets %}
        ...
        {% csrf_token %}
        <input type="text" name="q" id="news-search-term">
        <div id="news-search-results"></div>
       ...
        function submitSearchForm() {
        $.post("/myapp/news/search/",
            {   'q': $('#news-search-term').val(),
                'csrfmiddlewaretoken': $('input[name=csrfmiddlewaretoken]').val() },
            function(data){
                $('#news-search-results').html(data);
            } 
        );
    }
        {{ block.super }}
        {% endblock %}
    

    4) 我创建了一个用于显示结果的 html 模板(news_search_results.html,参见 1)

    所以基本上我是从管理页面向自定义视图发送 AJAX 请求,以从 web 服务中检索结果,然后将结果显示在 div 中。

    结果列表中的每个元素都有一个按钮,用于发送另一个请求,该请求将具有新闻 id 的元素存储为 ForeignKey。

    我不知道这是否特别违反 Django 原则。但它似乎工作正常。

    欢迎以更“Djangonian”的方式提出建议。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-08-26
      • 2019-08-07
      • 1970-01-01
      • 1970-01-01
      • 2014-02-06
      • 2017-05-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多