2013-06-30 1 views
4

여러 인스턴스가 여러 행에 대해 동일한 필드 (열) 값을 공유하는 모델에서 단일 인스턴스 (db 행)를 표시하려고합니다. 그 문을 명확히하기 위해, 나는 다음과 같은 상황이 있습니다Django Admin : 중복 인스턴스의 단일 인스턴스 표시

ID/Title/Slug/Modified 
1 Car  A 1s ago 
2 Car  A 2s ago 
3 House B 1s ago 

위의 작은 테이블 내 DB를 내 장고 관리자 페이지 내 슬러그 필드 (열) (마지막 편집 된 버전을 표시에 따라 별개의 행을 표시하려면한다면 나는 시간에 대한 또 다른 열이 ... 그래서 다음과 같이 위의 표는 관리자 페이지에 표시합니다 : 행 1 & 2는 같은 슬러그가 다른 PK의의를 가지고 있지만

ID/Title/Slug/Modified 
1 Car  A 1s ago 
3 House B 1s ago 

, 나는 그들 중 하나 싶어 나중 시간은 ...

existing_data = MyModel.objects.filter(slug=slug).latest('modified') 

을 다음하지만 슬러그의 특정 인스턴스를 찾고 있어요 때문에 내가 또한 GROUP_BY를 사용할 수 아니었다면 그 .. 것에 따라 나는 ...

내 views.py에이를 수 (3210)

관리자 페이지에서이 표시를 얻으려고합니다. 나는 모델 관리자에서 다음 방법을 시도했습니다,

class ModelManager(models.Manager): 
    def get_query_set(self): 
     return super(ModelManager, self).get_query_set().group_by('title') 

하지만 난 this part of the Django book을 읽고 있던이 오류 다음

'QuerySet' object has no attribute 'group_by' 

을 얻고 그들은 내가에 복사 시도 모델 관리자에서 원시 SQL을 구현 내 상황을 다음과 같이

class ModelManager(models.Manager): 
    def uniques(self): 
     cursor = connection.cursor() 
     cursor.execute(""" 
      SELECT * 
      FROM eventform_event 
      GROUP BY slug 
      """) 
     return [row[0] for row in cursor.fetchone()] 

임 내 모델 나는

admin 모델에서 get_query_set을 덮어 쓰지 않는 내 사용자 정의 관리자를 보는 방법을 모르겠습니다. 나는 get_query_set을 재정의이 사용자 정의 관리자를 사용 않았다 때 나는이 오류를 얻을

'long' object has no attribute '__getitem__' 

나는 또한 테스트의 가치를 시도했습니다(), values_list() 등) (별개하지만 그들은 모두 나에게 오류를 줄 ... distinct()는 내 데이터베이스 (mysql)가이 기능을 지원하지 않는다고 알려줍니다. 이제는이 기능을 구현하기 위해 데이터베이스를 전환해야하고 지금은 실험 할 아이디어가 없습니다. 이 기능 .. 고마워.

불행하게도 나는 행에 표시되지 않을 수 있습니다 내가 this thread 추천 당 슬러그 열을 기반으로 고유의 항목을 보여 측 필터 (list_filter)를 얻을 수 있습니다 내 admin.py 페이지에서

#

... 내 모델의 관리 페이지가 특정 열을 기반으로 고유하게 ...

답변

4

PostgreSQL에서 Django 1.4+를 사용하는 경우 queryset.distinct()에 * fields 인수를 사용할 수 있습니다. Django의 이전 버전을 사용하고 있거나 다른 데이터베이스 엔진을 사용하고 있다면 다른 방법으로 해결할 것입니다.

from django.db import models 

class TestModel(models.Model): 
    title = models.TextField(max_length=150) 
    slug = models.TextField(max_length=150) 
    modified = models.DateTimeField(auto_now=True) 

그런 다음 당신이 ModelAdmin의 queryset 방법으로이 작업을 수행 할 수 있습니다 :

from django.contrib import admin 

import models 

class TestModelAdmin(admin.ModelAdmin): 
    list_display = ('title', 'slug', 'modified') 

    def queryset(self, request): 
     qs = super(TestModelAdmin, self).queryset(request) 
     qs = qs.order_by('slug', '-modified').distinct('slug') 
     return qs 

admin.site.register(models.TestModel, TestModelAdmin) 

희망이 도움이

그래서 모델은 다음과 같이 보이는 경우.

편집 : 그래, 당신이 MySQL을 사용한다면 그것은 그리 산뜻하지 않다. Django 관리자는 RawQuerySet이 아닌 QuerySet으로 작업하기를 원하기 때문에 원시 SQL을 사용할 수 없습니다. 원시 SQL을 사용할 수 있다고해도 GROUP BY slug과 같이 간단하지는 않습니다. MySQL을 사용하면 테이블에 나타나는 순서대로 결과를 얻을 수 있기 때문입니다. 따라서 데이터가 다음과 같은 경우 :

+----+-------+------+---------------------+ 
| id | title | slug | modified   | 
+----+-------+------+---------------------+ 
| 1 | Car | A | 2013-06-30 20:18:06 | 
| 2 | House | B | 2013-06-30 20:18:12 | 
| 3 | Car | A | 2013-06-30 21:02:51 | 
| 4 | Thing | C | 2013-06-30 22:08:00 | 
| 5 | House | B | 2013-06-30 22:08:05 | 
+----+-------+------+---------------------+ 

슬러그로 그룹화하면 order by 절에 관계없이 ID 1,2 및 4가 표시됩니다. Django 관리자가 가장 최근에 수정 한 항목 (원하는 내용)을 표시하지 않기 때문에 우리는 실제로 3, 4 및 5의 ID를 원합니다. 그룹핑을하기 전에 사전 정렬 된 표에서 선택해야합니다. 내가 생각할 수있는

가장 좋은 방법은 내가에 PostgreSQL을위한 준 대답에 queryset 방법을 변경하는 것입니다 : 당신은 당신의 테이블의 기본 키의 이름으로 id을 변경해야합니다

def queryset(self, request): 
    qs = super(TestModelAdmin, self).queryset(request) 
    qs = qs.extra(where=[ 
     "id IN (
      SELECT id FROM (
       SELECT * FROM myapp_testmodel ORDER BY modified DESC 
      ) AS last_modified 
      GROUP BY slug)" 
    ]) 
    return qs 

, 테이블 이름에 myapp_testmodel을 입력하십시오.

+0

감사합니다. 내 데이터베이스 엔진으로 MySQL을 사용하고 있습니다. 이 프로젝트가이 시점에서 PostgreSQL로 옮길 수 있는지 알 수 없기 때문에 나는이 기능을 w/mysql으로 구현하는 데 도움을 주시면 감사하겠습니다 ... – user772401

+0

완벽하게 작동 한 @Kevin에게 감사드립니다! 난 당신이 장고 관리 쿼리 세트에 raw SQL을 넣을 수 있는지 몰랐다 – user772401

+0

누구도 MySQL 5.7에서 사용하려고 했습니까? 그것은 나를 위해 작동하지 않습니다. 아마도이 [문제] (http://stackoverflow.com/questions/40804597/error-1055-42000-expression-1-of-select-list-is-not-in-group-by-clause-t)로 인해, –

관련 문제