web-dev-qa-db-ja.com

Django adminで自動入力および自動インクリメントフィールドを作成する方法

[更新:質問のタイトルをより具体的に変更しました]

質問がうまくできなかった場合は申し訳ありませんが、これを行う方法がわかりません。

class WhatEver():
    number = model.IntegerField('Just a Field', default=callablefunction)
...

callablefunctionがこのクエリを実行する場所:

from myproject.app.models import WhatEver

def callablefunction():
    no = WhatEver.objects.count()
    return no + 1

次の番号を自動で書きたいのですが、どうしたらいいのかわかりません。

callablefunctionから、モデルをインポートできないというエラーがあります。これを行うには、もっと簡単な方法があるはずです。これを使う必要すらありませんが、pk番号でどうやって使うのかわかりません。

私はこれについてグーグルで調べました、そして私が見つけた唯一のことは数を自動的にインクリメントするためにsave()メソッドを使うことでした...しかし私はそれを<textfield>保存する前に...

あなたならどうしますか?

17
Oscar Carballal

了解しました!これが、Djangoで自動入力および自動インクリメントフィールドを作成する際に問題が発生したすべての人に役立つことを願っています。解決策は次のとおりです。

class Cliente(models.Model):
    """This is the client data model, it holds all client information. This
       docstring has to be improved."""
    def number():
        no = Cliente.objects.count()
        if no == None:
            return 1
        else:
            return no + 1

    clientcode = models.IntegerField(_('Code'), max_length=6, unique=True, \
    default=number)

    [... here goes the rest of your model ...]

注意してください:

  • number関数は引数を取りません(自分自身でさえも)
  • 書かれています[〜#〜] before [〜#〜]モデル内のすべて
  • これはDjango 1.2.1でテストされました

この関数は、clientcodeフィールドに次の番号を自動的に入力します(つまり、132のクライアントがある場合、次のクライアントを追加すると、フィールドにはclientcode番号133が入力されます)

PK番号も自動インクリメントされるため、これはほとんどの実際の状況ではばかげていることを私は知っていますが、Django admin内で自動入力または実用化する方法はありません。

[更新:コメントで述べたように、これに主キーを使用する方法はありますが、フィールドに入力されません保存]

23
Oscar Carballal

すべてのDjangoモデルにはすでに 自動生成された主キー

id = models.AutoField(primary_key=True)

既存の動作を複製しようとしているようです。オブジェクトの主キーを使用するだけです。

8
Yuval Adam

私もこの問題に遭遇しました。私のインスタンスは_customer.number_で、これは顧客Storeに関連していました。私は次のようなものを使いたくなりました:

_# Don't do this:

class Customer(models.Model):
    # store = ...
    number = models.IntegerField(default=0)

    def save(self, *args, **kwargs):
        if self.number == 0:
            try:
                self.number = self.store.customer_set.count() + 1
            else:
                self.number = 1
        super(Customer, self).save(*args, **kwargs)
_

上記はいくつかの問題を引き起こす可能性があります: 10人の顧客がいて、顧客番号6を削除したとします。次に追加される顧客は(一見)10番目の顧客で、2番目の顧客になります# 10.10。 (これにより、get()クエリセットで大きなエラーが発生する可能性があります)

私が最終的に得たのは次のようなものでした:

_class Store(models.Model):
    customer_number = models.IntegerField(default=1)

class Customer(models.Model):
    store = models.ForeignKey(Store)
    number = models.IntegerField(default=0)

    def save(self, *args, **kwargs):
        if self.number == 0:
            self.number = self.store.customer_number
            self.store.number += 1
            self.store.save()
        super(Customer, self).save(*args, **kwargs)
_

PS:

このフィールドに「before」と入力してほしいと何度か投げました。あなたがそれにアクセスできるように保存する前にそれを記入したかったと思います。つまり、このメソッドを使用すると、_store.customer_number_にアクセスして、次の番号を確認できます。

6
Jacob Valenta

コードにエラーがあるため、インポートできません。

from Django.db import models
class WhatEver(models.Model):
    number = models.IntegerField('Just a Field', default=0)

そして、Yuval Aは自動インクリメントについて正しいです:そのようなフィールドを宣言する必要さえありませんpkまたはidを使用するだけで、モデルに複合pkがない限り、同じ意味になります。

> w = Whatever(number=10)
> w
<Whatever object>
> w.id
None
> w.save()
> w.id
1

[更新]まあ、私はデフォルトとしてcallableを試していません。これらのエラーを修正すれば、うまくいくはずだと思います。

0
culebrón