Search code examples
djangodjango-formsdjango-admindjango-widget

Django: custom content in admin form


For one of my models, I want to show extra content in the change_form. Basically, my model looks like this:

class News(models.Model):
    ...

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

I want to add a 'search' button that, when clicked, triggers a web service request to an external news source, pulls down the available content, and lists all the news pieces contained. The user can then select one of the pieces to "attach" to the News currently edited in the admin interface (i.e. create a new NewsFromSource based on the content downloaded through the web service).

I am done with the web service. What is the best approach to implementing the search-button, list display for the results (I have a view and template that work, need to get those into the form somehow) and the saving part?


Solution

  • What I ended up doing is the following:

    1)

    I created a view for fetching search results, which boils down to this:

    #/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) I mapped the view:

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

    3) I extended change_form.html for the news model with the following code:

    #/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) I created an html template for displaying the results (news_search_results.html, see 1)

    So basically I am sending an AJAX request from the admin page to a custom view to retrieve results from the webservice which then are displayed in a div.

    Each element in the results list has a button that sends another request that stores the element with the news id as a ForeignKey.

    I have no idea whether this is particularly against Django principles. But it seems to work alright.

    Suggestions on doing this in a more "Djangonian" way are welcome.