我有一個模型,Director
有兩個DateFields和兩個子類(下面的代碼)。我試圖爲每個Director顯示相應的子類實例創建一個管理頁面,而不是Director
實例;這部分大部分都很簡單(我爲每個子類創建一個內聯,爲主ModelAdmin提供一個表單,其中包含所有字段除外,並且具有主要的僅限於ModelAdmin請求的內聯表單,它們具有相應的實例 - 代碼;存在未解決的問題用這種方法,我在下面注意到,但不是這個問題的焦點)。Django的管理員:如何格式化只讀字段?
我的問題是,我想按摩顯示給用戶的值,其中一個顯示在只讀字段中,其中一個不是。處理過程是我想將魔術值(date(1,1,1)
)更改爲字符串"On incorporation"
。
readonly字段中的日期不是以非常友好的解析格式呈現的,我想減少對javascript的不必要的依賴,所以我非常喜歡服務器端解決方案。
下面的代碼顯示了我希望它們的表格,不同之處在於日期值根本沒有被按摩,並且當保存時,即使沒有錯誤,也會出現假「請更正下面的錯誤」消息,並且所有字段保存正確。
我的問題是:如何攔截要在頁面上呈現的值,包括只讀字段和表單字段,並將其更改爲顯示我選擇的字符串?
這些模型(迄今爲止爲原料):
class Director(models.Model, Specializable):
date_of_appointment = models.DateField()
date_ceased_to_act = models.DateField(blank=True,null=True)
class DirectorsIndividual(Director):
pass
class DirectorsCorporate(Director):
pass
管理代碼:
class DirectorAdmin(EnhancedAdmin):
fields =()
## def formfield_for_dbfield(self, db_field, **kwargs):
## return None
def queryset(self, request):
""" Directors for all companies which are incorporated by the current user's organisation """
individual = Individual.for_user(request.user)
return Director.objects.filter(company__incorporation_ticket__ordered_by__in = Organisation.all_organisations_for_which_individual_authorised_to_incorporate(individual))
class form(forms.ModelForm):
# have this return no html - that way only inlines are shown
class Meta:
fields =()
pass
def is_valid(self):
self._errors = {}
return True
class DirectorsIndividualInline(admin.StackedInline):
model = DirectorsIndividual
fk_name = 'director_ptr'
extra = 0
readonly_fields = ('deferred_on','company','date_of_appointment',)
can_delete = False
def get_readonly_fields(self, request, obj=None):
if obj and obj.company and not obj.company.is_submitted(): return self.readonly_fields # allow editing of fields listed in else
else:
return itertools.chain(self.readonly_fields, ('individual', 'is_secretary'))
def has_delete_permission(self, request, obj=None):
return obj and ((obj.company and not obj.company.is_submitted()) or not obj.company)
class form(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(forms.ModelForm, self).__init__(*args, **kwargs)
self.fields['surrogate_for'].required = False
self.fields['representative_for'].required = False
if self.instance:
obj = self.instance
for field in (f for f in type(obj)._meta.fields if type(f) == fields.DateField):
val = field.value_from_object(obj)
assert (type(val) in (datetime.date, type(None),))
# assert field.name != 'date_of_appointment'
if val == inc_consts.EARLIEST_DATE:
self.initial[field.name] = "On incorporation"
def is_valid(self):
self._errors = {}
return True
class DirectorsCorporateInline(admin.StackedInline):
model = DirectorsCorporate
fk_name = 'director_ptr'
extra = 0
can_delete = False
class form(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(forms.ModelForm, self).__init__(*args, **kwargs)
if True:
for k in self.fields:
self.fields[k].required = False
def is_valid(self):
self._errors = {}
return True
inlines = (DirectorsIndividualInline,DirectorsCorporateInline)
def get_inlines(self, request, obj=None):
return (inline for inline in (self.inline_instances)
if inline.model.objects.filter(**{(inline.fk_name or self.model._meta.object_name.lower()) : obj }))
def get_formsets(self, request, obj=None):
""" only return formset for inlines for which there exists an object """
return (inline.get_formset(request, obj) for inline in self.get_inlines(request, obj))
我知道有DirectorsCorporateInline
和DirectorsIndividualInline
之間的不對稱;這是因爲我正在使用DirectorsIndividual
實例對實例進行測試。上面的代碼是指未在模型中顯示的模型字段,因爲它們對日期問題不重要;應該有可能在不改變這些領域的情況下使它們對於虛假錯誤問題不重要(儘管我認識到它對這個問題沒什麼幫助,但我想把這個問題主要集中在一個問題上)。 EnhancedAdmin
是一個ModelAdmin
子類,有一些小的改動,這不應該是後果。額外的代碼可以顯示在合理的請求,但我不想混淆不相關的代碼。
爲了完整:我在python 2.7.2上使用django 1.3.1。
他們並沒有真正呈現一致,這將使JavaScript使用痛苦;我可能不得不,所以謝謝你的信息。 – Marcin 2012-01-03 12:06:13