2017-09-06 22 views
0

私は1つを追加する必要がAdAdminで.extra()ジャンゴ - 管理者ListFilterクエリセットにwitnの.extra()

を使用してクエリセットにDjangoの管理list_filterを使用する方法に把握しようとしている複数の日モデルAdHistから新しい列「ad_hist_status_id」私はSomeListFilter上のコードのこの部分を使用できるように:

def queryset(self, request, queryset): 
    return queryset.filter(ad_hist_status_id=self.value()) 

それは不可能のように見えます。 SQLでこれを行うことは簡単です:

select a.*, ah.ad_hist_status_id from ad_ad a 
join ad_adhist ah on ah.ad_id = a.id 
where 
ah.datetime_end is null 
order by a.id DESC 

今まで私は、DjangoのAdminでこのSomeListFilterを動作させることはできません、エラーは次のとおりです。

FieldError at /admin/ad/ad/ 

Cannot resolve keyword 'ad_hist_status_id' into field. 
Choices are: addetailscategories, address, adhist, adphotos, 
adprice, adscheduleinfo, age, comment, county, county_id, 
date_inserted, date_updated, description, district, district_id, 
email, id, lat, lng, name, parish, parish_id, schedule_type, 
schedule_type_id, telephone, title, user_inserted, user_inserted_id, 
user_updated, user_updated_id 

私の質問があり、私は効果的に新しいを追加するにはどうすればよいです列をQuerySetに追加し、この新しいQuerySetを新しい列でどのようにクエリできますか?

怒鳴る私のコードの

いくつかの部分モデル:

class Ad(models.Model): 
    title = models.CharField(max_length=250) 
    name = models.CharField(max_length=100) 
    description = models.TextField() 
    age = models.IntegerField(blank=True, null=True) 
    telephone = models.CharField(max_length=25) 
    email = models.EmailField() 
    district = models.ForeignKey(District) 
    county = ChainedForeignKey(County, chained_field="district", chained_model_field="district", sort=True) # smart_selects app 
    parish = ChainedForeignKey(Parish, chained_field="county", chained_model_field="county", sort=True) # smart_selects app 
    address = models.CharField(max_length=250, null=True, blank=True) 
    lat = models.DecimalField(max_digits=9, decimal_places=6, null=True, blank=True) 
    lng = models.DecimalField(max_digits=9, decimal_places=6, null=True, blank=True) 
    schedule_type = models.ForeignKey(AdScheduleType) 
    comment = models.TextField(null=True, blank=True) 
    user_inserted = models.ForeignKey(User, null=True, blank=True, related_name='user_inserted_ad') 
    date_inserted = models.DateTimeField(auto_now_add=True) 
    user_updated = models.ForeignKey(User, null=True, blank=True, related_name='user_updated_ad') 
    date_updated = models.DateTimeField(null=True, blank=True) 

    def __str__(self): 
     return self.name 

class AdHist(models.Model): 
    ad = models.ForeignKey(Ad) 
    datetime_begin = models.DateTimeField() 
    datetime_end = models.DateTimeField(null=True, blank=True) 
    ad_hist_status = models.ForeignKey(AdHistStatus) 
    ad_hist_change_reason = models.ForeignKey(AdHistChangeReason) 
    comment = models.TextField(null=True, blank=True) 
    user_inserted = models.ForeignKey(User, null=True, blank=True, related_name='user_inserted_ad_hist') 
    date_inserted = models.DateTimeField(auto_now_add=True) 
    user_updated = models.ForeignKey(User, null=True, blank=True, related_name='user_updated_ad_hist') 
    date_updated = models.DateTimeField(null=True, blank=True) 

    def __str__(self): 
     return self.ad.name 

管理者:

class SomeListFilter(admin.SimpleListFilter): 
    title = _('Approval State') 
    parameter_name = 'ad_hist_status_id' 

    def lookups(self, request, model_admin): 
     return (
      ('1', _('Approved')), 
      ('4', _('Not Approved')), 
     ) 

    def queryset(self, request, queryset): 
     return queryset.filter(ad_hist_status_id=self.value()) 

class AdAdmin(admin.ModelAdmin): 
    list_display = ('id', 'name', 'title', 'age', 'telephone', 
        'email', 'district', 'county', 'parish', 
        'ad_status', 'ad_hist_change_reason', 'comment', 
        'user_inserted', 'date_inserted', 'user_updated', 
        'date_updated', 'ad_hist_status_id') 

    readonly_fields = ('ad_status', 'id', 'ad_hist_change_reason', 
        'ad_hist_status_id') 

    list_filter = (SomeListFilter,) 

    def get_queryset(self, request): 
     qs = super(AdAdmin,self).get_queryset(request).extra(select={'ad_hist_status_id': 'select ad_hist_status_id from ad_adhist where ad_adhist.ad_id = ad_ad.id and ad_adhist.datetime_end is null'},) 
     return qs 

    def ad_hist_status_id(self, inst): 
     return inst.ad_hist_status_id 

は、誰かが私に手掛かりを与えることはできますか?私は右のあなたの質問を理解していれば

よろしく

答えて

0

は、あなたはこのを探しています:

from django.db.models import F 

def queryset(self, request, queryset): 
    return queryset.filter(ad_hist_status__id=F('id')) 

F expressionを同じモデルからフィールドを参照するために使用され、およびからフィールドを参照するためにアンダースコア(__)を使用する必要があります。

+0

こんにちははAnkur。返事をありがとう。モデルAdは動作しませんでしたが、AdHistを指すキーがなく、AdHistだけがAdを指しています。すべての手がかりは? –

+0

これを試しましたか? AdHistにはAdに対する外部キーがありますが、AdからAdHistにアクセスすることはできません。これを試した後で確認してください。 –

0

Django field lookupsを詳しく見てください。ドキュメントの内容を確認してください。

基本的な検索キーワード引数の形式は、field__lookuptype=valueです。 (それは二重アンダーバーです)。

あなたは、関連AdHistStatusを有し、AdからAdHist関連オブジェクトを取り、そのidを取得したいです。

だから、のようなこのidフィールドにアクセスする必要があります

def ad_hist_status_id(self, instance): 
    return instance.adhist.ad_hist_status.id 

それとも、ダブルアンダースコア構文で直接それを一覧表示することができます:

class AdAdmin(admin.ModelAdmin): 
    list_display = (..., 'adhist__ad_hist_status__id') 
+0

こんにちは。返信いただきありがとうございます。それは動作しません、私に同じエラーを与える。Adモデルが表示され、AdHistを指すキーがない場合、AdHistだけがAdを指し示します。どんな社会的手がかりも? –

+0

@André私は今ここで問題に気づいたと思います。あなたの 'AdHist'モデルはあなたの' Ad'との外的な関係を持っています。これは** "1つのAd"には多くのAdHistがあります**。したがって、 'Ad'インスタンスの' AdHist'エントリのリストがあります。これは 'ad.adhist_set'でアクセスすることができます。 'ForeignKey'の代わりに' OneToOne'関係を持たせたいと考えてください。 – wencakisa

+0

こんにちはwencakisa。 AdHistはAdへの複数のキー参照を持つため、OneToOneは機能しません。それ以上の手がかりは? –

関連する問題