首页 > 解决方案 > How to add custom view page to django admin?

问题描述

I have a parent-child models.
It's kind of a coctail recipe, but it's about fish foods.

I want to give a recipe calculator for each recipe.
My current approach simply just add a link column at the list-view

Normal change list here is a snip of my admin.py

class BahanCampuranAdmin(admin.ModelAdmin):
    list_display = ('name','_isfood', '_vubuy','_pbuy','userv','uconv','_bikin')
    fields = ('isfood','name', 'ubuy', 'vbuy','userv','uconv')
    readonly_fields = ['pbuy']
    inlines = [
            KomponenCampuranAdmin,
        ]

    def get_queryset(self, request):
        qs = super().get_queryset(request)
        return qs.filter(user=request.user)


    def _bikin(self,obj):
        if obj.ingridient.exists() :
            link="<a href='/catatkolam/recipecalc/{0}'>bikin</a>"
            return format_html(link, obj.id)
        return '-'
    _bikin.allow_tags=True
    _bikin.short_description='Bkin'

...

This is what I got when clicking the link at the rightmost column. Current recipe calc

Look that it throw the user out of 'admin site'

Here is my current template.

{% extends "admin/base.html" %}

{% block content %}

  
<style>
.Recipe-IngredientList {
  width: 250px;
  border: 1px solid #777;
  border-radius: 3px;
  padding: 5px;
  margin-top: 5px;
}
.Recipe-Ingredient {
  border-bottom: 1px solid black;
  padding: 5px 0;
}
.Recipe-Ingredient:last-child {
  border-bottom: none;
}
.Recipe-Ingredient span {
  font-weight: 600;
}
</style>

  <script>
  window.console = window.console || function(t) {};
</script>

  
  
  <script>
  if (document.location.search.match(/type=embed/gi)) {
    window.parent.postMessage("resize", "*");
  }
</script>


<div>
    <label for="serving">
      <h3>{{name}}</h3>
      <input type="number" id="servingInput" value={{vbuy}}>
      <span STYLE="font-weight:bold">{{ubuy}}</span>
    </label>

  <div class="Recipe-IngredientList">
    {%for k in komponen%}
      <div class="Recipe-Ingredient js-recipeIngredient" data-baseValue={{k.qty}}>{{k.name}} : <span></span> {{k.userv}}</div>
    {% endfor %}
  </div>
</div>


<script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js'></script>
<script id="rendered-js" >
// Recipe calculator with jquery
var computeServing = function (serving) {
  $('.js-recipeIngredient').each(function (index, item) {
    $(item).children('span').html(($(item)[0].dataset.basevalue * serving).toFixed(2));
  });
};
$('#servingInput').on('change', function () {
  computeServing($(this).val());
});

computeServing(1);

</script>
{% endblock %}

and here is my app's urls.py

from django.urls import path

from . import views
app_name = 'catatkolam'
urlpatterns = [path('', views.index , name='index'),
    path('/recipecalc/<int:id>', views.recipecalc , name='recipecalc')]

My question is: How to show that recipe calculator still inside the admin site?
Like :

what I want

标签: django

解决方案


Define that URL in get_urls method of your BahanCampuranAdmin class and wrap your view in self.admin_site.admin_view.

    def get_urls(self):
        urls = super().get_urls()
        custom_urls = [
            path('/recipecalc/<int:id>', self.admin_site.admin_view(views.recipecalc) , name='recipecalc'),
        ]
        return custom_urls + urls

推荐阅读