TL; DRこれはDjango 1.7のバグで、Django 1.8で修正されました。
変更をマスターし、直接行って、あまりない非推奨期間、下行きませんでした下位互換性を維持することが本当に困難だったことを考えると驚くべきことです。もっと驚くべきことは、修正プログラムが現在動作しているコードの動作を変更するため、1.8 release notesにその問題が記載されていないことです。
残りの回答は、git bisect run
を使用してコミットを見つけた方法の説明です。それは何よりも私の自身の参考のためにここにあります。だから、大きなプロジェクトをもう一度二等分する必要があるなら、私はここに戻ってきます。
最初に、問題を再現するためのdjangoクローンとテストプロジェクトをセットアップしました。私はここでvirtualenvwrapperを使っていましたが、あなたが望むように分離を行うことができます。
cd /tmp
git clone https://github.com/django/django.git
cd django
git checkout tags/1.7
mkvirtualenv djbisect
export PYTHONPATH=/tmp/django # get django clone into sys.path
python ./django/bin/django-admin.py startproject djbisect
export PYTHONPATH=$PYTHONPATH:/tmp/django/djbisect # test project into sys.path
export DJANGO_SETTINGS_MODULE=djbisect.mysettings
次のファイルを作成します。今、私たちはgit bisect run
で使用するtest_script.py
を作成し、作業プロジェクトを持っている
# /tmp/django/djbisect/djbisect/mysettings.py
from djbisect.settings import *
INSTALLED_APPS += ('djbisect',)
:
#!/usr/bin/env python
import subprocess, os, sys
db_fname = '/tmp/django/djbisect/db.sqlite3'
if os.path.exists(db_fname):
os.unlink(db_fname)
cmd = 'python /tmp/django/djbisect/manage.py migrate --noinput'
subprocess.check_call(cmd.split())
import django
django.setup()
from django.contrib.contenttypes.models import ContentType
from djbisect.models import GFKmodel, GRmodel
ct = ContentType.objects.get_for_model(GRmodel)
y = GRmodel.objects.create(pk=456)
x = GFKmodel.objects.create(pk=789, content_type=ct, object_id=y.pk)
query1 = GRmodel.objects.values_list('related_gfk', flat=1)
query2 = GRmodel.objects.values_list('related_gfk__pk', flat=1)
print(query1)
print(query2)
print(query1.query)
print(query2.query)
if query1[0] == 789 == query2[0]:
print('FIXED')
sys.exit(1)
else:
print('UNFIXED')
sys.exit(0)
# /tmp/django/djbisect/djbisect/models.py
from django.db import models
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation
class GFKmodel(models.Model):
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
gfk = GenericForeignKey()
class GRmodel(models.Model):
related_gfk = GenericRelation(GFKmodel)
も、このいずれかを
スクリプトは実行可能でなければならないので、フラグにchmod +x test_script.py
を追加してください。これは、Djangoがクローンに登録されているディレクトリ、つまり/tmp/django/test_script.py
にあります。これは、import django
がsite-packagesからのバージョンではなく、ローカルでチェックアウトされたdjangoプロジェクトを最初にピックアップするからです。
gitの二分のユーザーインターフェースは、見つけるために設計されていたところ、あるバグが修正さたとき、あなたが見つけるためにしようとしているとき登場バグなので、「悪い」と「良い」の通常の接頭辞が後方にあります。これはやや逆さまに見えるかもしれませんが、バグがあればテストスクリプトは成功(リターンコード0)し、バグが修正された場合は(ゼロ以外のリターンコードで)失敗するはずです。これは私を数回上手くしました!
git bisect start --term-new=fixed --term-old=unfixed
git bisect fixed tags/1.8
git bisect unfixed tags/1.7
git bisect run ./test_script.py
このプロセスでは、最終的にバグが修正されたコミットを見つける自動検索が行われます。 Django 1.7とDjango 1.8の間にはたくさんのコミットがあったので、時間がかかりました。
SELECT "djbisect_gfkmodel"."object_id" FROM "djbisect_grmodel" LEFT OUTER JOIN "djbisect_gfkmodel" ON ("djbisect_grmodel"."id" = "djbisect_gfkmodel"."object_id" AND ("djbisect_gfkmodel"."content_type_id" = 8))
クエリが(間違ったテーブルからデータを取得します)不正なSQLから変更されている場所を正確にコミットしています
1c5cbf5e5d5b350f4df4aca6431d46c767d3785a is the first fixed commit
commit 1c5cbf5e5d5b350f4df4aca6431d46c767d3785a
Author: Anssi Kääriäinen <[email protected]>
Date: Wed Dec 17 09:47:58 2014 +0200
Fixed #24002 -- GenericRelation filtering targets related model's pk
Previously Publisher.objects.filter(book=val) would target
book.object_id if book is a GenericRelation. This is inconsistent to
filtering over reverse foreign key relations, where the target is the
related model's primary key.
:それは1362の改正、およそ10段階、そして最終的に出力を二分しました正しいバージョン:
SELECT "djbisect_gfkmodel"."id" FROM "djbisect_grmodel" LEFT OUTER JOIN "djbisect_gfkmodel" ON ("djbisect_grmodel"."id" = "djbisect_gfkmodel"."object_id" AND ("djbisect_gfkmodel"."content_type_id" = 8))
もちろん、コミットハッシュから、githubでプルリクエストとチケットを簡単に見つけることができます。 Djangoを二分することは、移行のために設定するのが難しいかもしれません!
*注意:* Djangoのバージョンは '(1、7、11、 'final'、0)'です。私はこれをDjango 1.8で再現することはできません。 – wim
これは、Django 1.7では1.8に修正することを決めたということでしょうか? – mgilson
可能ですが、リリースノートの中で高低を検索して見つけられませんでした。 'git bisect'がそれを見つけることができると思います.... – wim