2010-06-26 69 views
13

[更新:更改問題的標題更具體]如何使自動填充和Django管理自動遞增的字段

很抱歉,如果我沒有做這個問題非常好,我可以」 W圖如何做到這一點:

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 

我想自動寫入下一個編號, nd我不知道該怎麼做。

我從callablefunction錯誤,指出它不能導入模型,我認爲必須有一個更簡單的方法來做到這一點。甚至沒有必要使用這個,但我不知道如何使用PK號碼。

我GOOGLE了這件事,我發現的唯一的事情是使用自動遞增的數量save()方法...但我想說的是,在<textfield>保存前...

你會怎麼做?

回答

19

Got it!我希望這可以幫助每個有任何問題的人在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函數不帶任何參數(甚至沒有個體經營)
  • 這是寫一切都在模型
  • 這在django上測試過1.2.1

這個有趣ction會自動填入clientcode字段中的下一個數字(即如果你有132個客戶,當你添加下一個時,該字段將填充clientcode 133)

我知道這對大多數實際情況來說是荒謬的,因爲PK號碼也是自動遞增的,但是django管理員無法自動填充或實際使用它。

[更新:正如我在評論中所說的,是用於該主鍵的方式,但保存前,將不會填補該領域]

+5

你確定這段代碼也可以用於併發事務嗎?當兩個請求同時執行'count()'時會發生什麼,並在稍後寫入相同的值? – vdboor 2010-06-28 08:53:06

+0

這是真的......在我的使用案例中,這並不重要,因爲一次不會有兩個請求......但即使如此,我仍然必須考慮更好的方法來實現此目的。感謝您的建議! :) – 2010-06-28 13:13:44

+0

我已經能夠執行類似於我想要做這個字段的東西:'id = models.IntegerField(primary_key = True,blank = True)'唯一的是它不是自動填充的,但解決了問題的同時請求(我認爲) – 2010-06-28 15:49:34

6

每Django的模型已經有一個auto-generated primary key

id = models.AutoField(primary_key=True) 

似乎您試圖複製一個已經存在的行爲,只需要使用對象的主鍵。

+0

我知道主鍵,但我必須在django管理頁面中顯示該數字。有沒有辦法做到這一點? – 2010-06-26 13:11:56

+0

請參閱http://stackoverflow.com/questions/2531762/edit-show-primary-key-in-django-admin – 2010-06-26 13:17:02

+0

這是行不通的。如果你把它作爲AutoField Django崩潰。如果它的IntegerField不能按預期工作。它只是成爲一個普通的IntegerField。我需要該字段自動填充下一個數字(我認爲我很糟糕的解釋我自己) – 2010-06-26 13:30:30

0

你有錯誤的代碼,這就是爲什麼你不能導入:

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

和尤瓦A是正確的關於自動遞增:你甚至都不需要聲明這般田地。只需使用pkid,他們的意思是相同的,除非有模型的複合PK:

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

[更新]好了,我還沒有試過一個可調用作爲默認值。我認爲如果你解決了這些錯誤,它必須奏效。

+0

我認爲至於django 1.2.1 Field.default()可以有一個可調用的對象,而不只是一個數字/字符串 – 2010-06-26 13:21:43

6

我也碰到這個問題來了,我的例子是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客戶,這將成爲第二個客戶#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:

你拋出了幾次,你想這個字段填寫「之前「。我想你希望在保存之前填寫它,以便可以訪問它。對此我會說:這種方法可以讓你訪問store.customer_number看到下一個號碼來。

+0

儘管這樣可以解決重複的問題,但是如果我刪除了其中的項目,仍然會出現空白。不能用作表格中元組的索引號。 – 2014-09-22 06:10:10

+0

有什麼辦法可以產生連續的數字,最後一個數字的值應該等於'count()'。所有數字都應該在刪除條目時更新?我想這可以做刪除事件檢測和使用循環來更新所有條目。但我不知道如何在django模型中做到這一點。你可以編輯你的代碼來解決這個問題。 – 2014-09-22 06:20:15

+2

我做的工作方法就像自動增量一樣,它不會重複使用數字。你可以編寫一個循環去更新數字,但它可能並不值得[你]寫這個函數的時間,並且不值[計算機]運行它的時間。即使是一個小型數據庫,打出所有這些記錄的時間也可能非常巨大。 – 2014-09-22 14:14:20