35

私は現在、多くの集団的知性を含むプロジェクトを構築しています。Webサイトにアクセスするすべてのユーザーは、一意のプロファイルを作成され、それらのデータは、後で自分自身と他のユーザーの最適な一致を計算するために使用されます。

デフォルトでは、Djangoはidモデルの主キーを処理するためのINT(11)フィールドを作成します。私はこれが非常に急速にオーバーフローすることを懸念しています(つまり、事前にCookieを設定せずにページにアクセスするデバイスは約2.4b)。MySQLではBIGINTとして、Django自体ではlong()として表されるように変更するにはどうすればよいですか?

私は次のことができることを発見しました(http://docs.djangoproject.com/en/dev/ref/models/fields/#bigintegerfield):

class MyProfile(models.Model):
    id = BigIntegerField(primary_key=True)

idしかし、通常のフィールドのように、それを自動インクリメントする方法はありますか?さらに、入力するスペースを増やすために、署名なしにすることはできますか?

ありがとう!

4

7 に答える 7

20

Django 1.10を使用している場合、DjangoにはBigAutoFieldが組み込まれています。

https://docs.djangoproject.com/en/1.10/ref/models/fields/#bigautofield

于 2016-07-27T21:54:48.953 に答える
19

lfagundesに触発されましたが、小さいながらも重要な修正が加えられています。

class BigAutoField(fields.AutoField):
    def db_type(self, connection):  # pylint: disable=W0621
        if 'mysql' in connection.__class__.__module__:
            return 'bigint AUTO_INCREMENT'
        return super(BigAutoField, self).db_type(connection)

add_introspection_rules([], [r"^a\.b\.c\.BigAutoField"])

BigIntegerFieldを拡張する代わりに、AutoFieldを拡張していることに注意してください。これは重要な違いです。AutoFieldを使用すると、DjangoはデータベースからAUTO INCREMENTed IDを取得しますが、BigIntegerは取得しません。

BigIntegerFieldからAutoFieldに変更する際の1つの懸念は、AutoFieldのintへのデータのキャストでした。

DjangoのAutoFieldからの通知:

def to_python(self, value):
    if value is None:
        return value
    try:
        return int(value)
    except (TypeError, ValueError):
        msg = self.error_messages['invalid'] % str(value)
        raise exceptions.ValidationError(msg)

def get_prep_value(self, value):
    if value is None:
        return None
    return int(value)

Pythonシェルで検証されているように、これは問題ないことがわかります。

>>> l2 = 99999999999999999999999999999
>>> type(l2)
<type 'long'>
>>> int(l2)
99999999999999999999999999999L
>>> type(l2)
<type 'long'>
>>> type(int(l2))
<type 'long'>

つまり、intにキャストしても、数値が切り捨てられたり、基になる型が変更されたりすることはありません。

于 2013-06-11T02:51:53.317 に答える
15

注:この回答は、ラリーのコードに従って変更されたものです。以前のソリューションはfields.BigIntegerFieldを拡張しましたが、fields.AutoFieldを拡張する方が適切です

私は同じ問題を抱えていて、次のコードで解決しました:

from django.db.models import fields
from south.modelsinspector import add_introspection_rules

class BigAutoField(fields.AutoField):
    def db_type(self, connection):
        if 'mysql' in connection.__class__.__module__:
            return 'bigint AUTO_INCREMENT'
        return super(BigAutoField, self).db_type(connection)

add_introspection_rules([], ["^MYAPP\.fields\.BigAutoField"])

どうやらこれは南の移行でうまく機能しています。

于 2011-09-16T17:32:27.303 に答える
7

後でテーブルを変更できます。それはより良い解決策かもしれません。

于 2010-04-20T10:17:53.833 に答える
3

前に述べたように、後でテーブルを変更できます。それは良い解決策です。

これを忘れずに行うには、アプリケーションパッケージの下に管理モジュールを作成し、post_syncdbシグナルを使用します。

https://docs.djangoproject.com/en/dev/ref/signals/#post-syncdb

これにより、django-admin.pyフラッシュが失敗する可能性があります。しかし、それでも私が知っている最良の選択肢です。

于 2011-11-22T03:29:19.743 に答える
2

私も同じ問題を抱えていました。djangoではBigInteger自動フィールドがサポートされていないようです。

カスタムフィールドBigIntegerAutoFieldを作成しようとしましたが、サウスマイグレーションシステムで問題が発生しました(サウスはフィールドのシーケンスを作成できませんでした)。

いくつかの異なるアプローチを試した後、私はマシューのアドバイスに従い、テーブルを変更することにしました(例: ALTER TABLE table_name ALTER COLUMN id TYPE bigint;postgre)

django(BigIntegerAutoFieldに組み込まれているような)とsouthでソリューションがサポートされていると便利です。

于 2010-06-06T12:33:16.413 に答える
2

DEFAULT_AUTO_FIELDDjango 3.2以降、暗黙の主キーのタイプは設定(ドキュメント)で制御できます。したがって、すべてのモデルで主キーをオーバーライドする必要はもうありません。

#This setting will change all implicitly added primary keys to BigAutoField
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'

Django 3.2以降、(リリースノートDEFAULT_AUTO_FIELD)に設定して新しいプロジェクトが生成されることに注意してください。BigAutoField

于 2021-11-25T14:19:00.947 に答える