Django ModelAdmin get_object optimization

时间:2016-12-28 09:26:48

标签: django django-admin

我在Django ModelAdmin列表视图中优化了get_queryset

  • .only('field1', 'field2',)
  • .select_related('rel1',)

这些优化与get_object更改视图所需的不同:

  • .only('field1', 'field2', 'field3',)
  • .select_related('rel1__rel2', 'rel3',)
  • .prefetch_related(...)

事情是,get_queryset and get_object are coupled

class BaseModelAdmin(...):

  ...

  def get_object(self, request, object_id, from_field=None):
      """
      Returns an instance matching the field and value provided, the primary
      key is used if no field is provided. Returns ``None`` if no match is
      found or the object_id fails validation.
      """
      queryset = self.get_queryset(request)
      model = queryset.model
      field = model._meta.pk if from_field is None else model._meta.get_field(from_field)
      try:
          object_id = field.to_python(object_id)
          return queryset.get(**{field.name: object_id})
      except (model.DoesNotExist, ValidationError, ValueError):
          return None

如何在不必复制/粘贴上面的所有锅炉板的情况下覆盖get_queryset

2 个答案:

答案 0 :(得分:1)

您的用例并不常见,因此我认为没有任何明智的方法可以在不重写get_object的情况下实现您的需求。我会做这样的事情:

# A parameter with default False value shouldn't screw things up
def get_queryset(request, for_object=False):
    qs = super(YourModelAdmin, self).get_queryset(request)
    if for_object:
        qs = qs.select_related('rel1__rel2', 'rel3')
        qs = .prefetch_related('rel4', 'rel5')
        return qs.only('field1', 'field2', 'field3')
    else:
        qs = qs.select_related('rel1')
        return qs.only('field1', 'field2')

def get_object(self, request, object_id, from_field=None):
    # Don't forget to add new param here
    queryset = self.get_queryset_for_object(request, for_object=True)
    model = queryset.model
    field = model._meta.pk if from_field is None else model._meta.get_field(from_field)
    try:
        object_id = field.to_python(object_id)
        return queryset.get(**{field.name: object_id})
    except (model.DoesNotExist, ValidationError, ValueError):
        return None

答案 1 :(得分:1)

我已经提出了这个解决方案,这似乎是一个很好的妥协:

<!DOCTYPE HTML>
<html>
  <head>
  <title>Donovan_D Minecraft - Youtube Description Template</title>
</head>
<body>
  <h3>To View HTML Click <a href="code.txt">Here </a></h3><br>
  <!--Start Template-->
  <div>===================================<br>
    My Channel:<br>
    https://youtube.com/c/DonovanDMinecraft<br>
    ===================================<br>
    Twitch:<br>
    http://twitch.tv/donovan_dmc<br>
    Twitter:<br>
    http://twitter.com/Donovan_DMC<br>
    ===================================<br>
    Sub2Janabell:<br>
    https://youtube.com/channel/UC0NTNba35ADUstIoLmYLiiA<br>
    ===================================<br>
    My <span style="text-decoration:underline;" id="v">1.9, 1.10, 1.11</span> Skyblock/Guilds Server:<br>
    IP: play.mcpsb.co<br>
    Server store:<br>
    http://store.mcpsb.co<br>
    Server Website:<br>
    https://www.mcpsb.co<br>
    ===================================<br>
    Thanks for <span style="text-decoration:underline;" id="sub">970</span> Subscribers! make sure to like, comment, subscribe, and Stay Awesome!
     ===================================<br>
    <!--End Template-->
    <hr>
    NOT PART OF TEMPLATE<br>
  </div>
  <b>Version:</b><br>
  Change: <input id="vr"><br>
  <button onclick="ver()">Update Version</button><br>
  <hr>
  <b>Subscriber Count:</b><br>
  Change: <input id="cs"><br>
  <button onclick="csub()">Update Subscriber Count</button><br>
  <hr>

  <script type="text/javascript">
    // Get/set form-field values using the .value property
    // Get/set non-form-field values with either .textContent or .innerHTML

    function ver() {
      document.getElementById("v").textContent = document.getElementById("vr").value;
    }
    
    function csub() {
      document.getElementById("sub").textContent = document.getElementById("cs").value;
    }
  </script>

    </body>
    </html>