Employee
、firstname
、およびlastname
フィールドを含む簡単なmiddlename
モデルがあります。
管理者側とおそらく他の場所で、私はそれを次のように表示したいと思います:
_lastname, firstname middlename
_
私にとってこれを行う論理的な場所は、計算フィールドを次のように作成することによるモデル内です。
_from Django.db import models
from Django.contrib import admin
class Employee(models.Model):
lastname = models.CharField("Last", max_length=64)
firstname = models.CharField("First", max_length=64)
middlename = models.CharField("Middle", max_length=64)
clocknumber = models.CharField(max_length=16)
name = ''.join(
[lastname.value_to_string(),
',',
firstname.value_to_string(),
' ',
middlename.value_to_string()])
class Meta:
ordering = ['lastname','firstname', 'middlename']
class EmployeeAdmin(admin.ModelAdmin):
list_display = ('clocknumber','name')
fieldsets = [("Name", {"fields":(("lastname", "firstname", "middlename"), "clocknumber")}),
]
admin.site.register(Employee, EmployeeAdmin)
_
最終的には、名前フィールドの値を文字列として取得する必要があると思います。私が得ているエラーはvalue_to_string() takes exactly 2 arguments (1 given)
です。文字列への値には_self, obj
_が必要です。 obj
の意味がわかりません。
これを行う簡単な方法がなければなりません、私はこれをしたい最初の人ではないと確信しています。
編集:これはダニエルの答えに修正された私のコードです。私が得るエラーは次のとおりです:
_Django.core.exceptions.ImproperlyConfigured:
EmployeeAdmin.list_display[1], 'name' is not a callable or an
attribute of 'EmployeeAdmin' of found in the model 'Employee'.
from Django.db import models
from Django.contrib import admin
class Employee(models.Model):
lastname = models.CharField("Last", max_length=64)
firstname = models.CharField("First", max_length=64)
middlename = models.CharField("Middle", max_length=64)
clocknumber = models.CharField(max_length=16)
@property
def name(self):
return ''.join(
[self.lastname,' ,', self.firstname, ' ', self.middlename])
class Meta:
ordering = ['lastname','firstname', 'middlename']
class EmployeeAdmin(admin.ModelAdmin):
list_display = ('clocknumber','name')
fieldsets = [("Name", {"fields":(("lastname", "firstname", "middlename"), "clocknumber")}),
]
admin.site.register(Employee, EmployeeAdmin)
_
わかりました...ダニエル・ローズマンの答えはうまくいくはずだったようです。いつものように、質問を投稿した後探しているものを見つけます。
Django 1.5 docsで私はこの例を見つけました からすぐに動作しました。ご協力ありがとうございます。
動作したコードは次のとおりです。
from Django.db import models
from Django.contrib import admin
class Employee(models.Model):
lastname = models.CharField("Last", max_length=64)
firstname = models.CharField("First", max_length=64)
middlename = models.CharField("Middle", max_length=64)
clocknumber = models.CharField(max_length=16)
def _get_full_name(self):
"Returns the person's full name."
return '%s, %s %s' % (self.lastname, self.firstname, self.middlename)
full_name = property(_get_full_name)
class Meta:
ordering = ['lastname','firstname', 'middlename']
class EmployeeAdmin(admin.ModelAdmin):
list_display = ('clocknumber','full_name')
fieldsets = [("Name", {"fields":(("lastname", "firstname", "middlename"), "clocknumber")}),
]
admin.site.register(Employee, EmployeeAdmin)
それはあなたがフィールドとしてすることではありません。その構文が機能していても、クラスにアクセスしたときではなく、クラスが定義されたときにのみ値を提供します。これをメソッドとして実行する必要があり、@property
デコレータを使用して、通常の属性のように見せます。
@property
def name(self):
return ''.join(
[self.lastname,' ,', self.firstname, ' ', self.middlename])
self.lastname
などは単なる値として表示されるため、他のメソッドを呼び出して変換する必要はありません。
Daniel Rosemanのソリューションは、計算フィールドをModel
の属性にしますが、それは QuerySetメソッドを介してアクセス可能にしません (例えば、。all()
、.values()
)。これは、QuerySetメソッド データベースを直接呼び出す であり、Django Model
。
QuerySetsはデータベースに直接アクセスするため、解決策は、計算フィールドを追加してManager
の.get_queryset()
メソッドをオーバーライドすることです。計算フィールドは、.annotate()
を使用して作成されます。最後に、objects
のModel
Managerを新しいManager
に設定します。
これを示すコードを次に示します。
models.py
from Django.db.models.functions import Value, Concat
from Django.db import Model
class InvoiceManager(models.Manager):
"""QuerySet manager for Invoice class to add non-database fields.
A @property in the model cannot be used because QuerySets (eg. return
value from .all()) are directly tied to the database Fields -
this does not include @property attributes."""
def get_queryset(self):
"""Overrides the models.Manager method"""
qs = super(InvoiceManager, self).get_queryset().annotate(link=Concat(Value("<a href='#'>"), 'id', Value('</a>')))
return qs
class Invoice(models.Model):
# fields
# Overridden objects manager
objects = InvoiceManager()
これで、.values()
または.all()
を呼び出して、link
で宣言された新しく計算されたManager
属性にアクセスできるようになります。
.annotate()
のようなF()
で その他の関数 を使用することも可能でした。
この属性はobject._meta.get_fields()
でまだ利用できないと思います。ここに追加できると思いますが、どのように編集したかコメントがあると便利です。
私は最近、あなたが抱えている問題を非常に簡単に解決できるライブラリに取り組みました。
https://github.com/brechin/Django-computed-property
それをインストールし、INSTALLED_APPSに追加してから
class Employee(models.Model):
...
name = computed_property.ComputedCharField(max_length=3 * 64, compute_from='full_name')
@property
def full_name(self):
return '{LAST}, {FIRST} {MIDDLE}'.format(LAST=self.lastname, FIRST=self.firstname, MIDDLE=self.middlename')
この場合、管理サイトおよびそのような問題での表現にのみフィールドを使用する場合は、str()またはunicode()Django documentation here :
class Employee(models.Model):
# fields definitions
def __str__(self):
return self.lastname + ' ,' + self.firstname + ' ' + self.middlename