我有一個TextField,其中的文本來自admin中的txt文件。我的txt有換行符。問題在於TextField處於readonly_fields中時,所有換行符便宜且所有內容都分組。 如何在readonly_fields模式下使用此字段的格式? 當不在readonly_fields時,問題不會發生。 謝謝!使用admin中的readonly_fields保留TextField中的格式文本
回答
的文本中的換行符通常由字符\n
或\r
或經常\r\n
(看看這個article on wikipedia獲取更多信息)表示。
您遇到的問題是這些字符將用於在文本編輯字段中顯示新行,但它們不代表html中的新行(它們將被忽略)。
如果您希望它們顯示在只讀字段中,那麼您可以用<br/>
元素替換它們。
如果您可以將您的字符串標記爲safe(即,如果您可以安全地添加html代碼而沒有任何人使用該字段添加惡意代碼的風險),那麼您可以覆蓋模型上的保存方法以換出文本行減免HTML換行符 -
from django.utils.safestring import mark_safe
def save(self, *args, **kwargs):
self.text_field = mark_safe(self.text_field.replace("\n", "<br/>"))
super(YourModel, self).save(*args, **kwargs)
另一種方法是使用一個插件添加全文格式化功能,例如django-tinymce。
我最後的建議是用javascript來破解它。將admin文件夾添加到您的模板中,然後創建一個base_site.html文件,該文件擴展了原始文件並添加了一個簡單的javascript函數(如here所述)。喜歡的東西 -
{% extends "admin/base.html" %}
{% block extrahead %}
<script type="text/javascript">
window.onload = function() {
var p_elements = document.getElementById('content-main').getElementsByTagName('p');
var unixNewLine = new RegExp("\n", "g");
for (var i = p_elements.length - 1; i >= 0; i--) {
p_elements[i].innerHTML = p_elements[i].innerHTML.replace(unixNewLine, '<br/>');
}
}
</script>
{% endblock %}
你需要添加一個replace
對每種類型的新線在你的文字(例如\r
,\r\n
)有。雖然這可能會做你所需要的,但它似乎是最糟糕的黑客。
當您查看頁面的源代碼時,會看到換行符。該空格在瀏覽器中顯示爲單個空格。您需要將所有換行符(\n
)轉換爲HTML換行符(<br />
)以使其看起來像您想要的樣子。
選項1:jQuery來拯救。
事情是這樣的:
<script type="text/javascript">
(function($) {
$(document).ready(function() {
// Adjustments for read-only fields:
// a) Convert quoted HTML entities back to HTML
$('.readonly').each(function() {
// Ensure there isn't valid html in the field
// The RegEx checks for any valid html opening tag
{% comment %}
TODO: It would be better to check against a special class name
on the widget
{% endcomment %}
if ($(this).html().match(/<(\w+)((?:\s+\w+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)>/) == null) {
$(this).html($(this).text());
$('ul', this).addClass('with_bullet');
$('li', this).addClass('with_bullet');
}
});
// b) Insert into empty <p>'s (m2m fields) so they don't break layout
// (see comment on text nodes: http://api.jquery.com/empty-selector/)
$('p.readonly:empty').each(function() { $(this).html(' ') })
});
})(django.jQuery);
</script>
(注:我們增加了「with_bullet」類,因爲我們使用格拉佩利和UL的李的get風格沒有子彈(列表樣式類型:無)等等這是使它們重新出現在我們自己的CSS中的一種方式...) 還要注意最後的佈局修復,我認爲這在後來的grappelli版本中不需要。
選項2:猴補丁django.contrib.admin.helpers.AdminReadonlyField:
from django.contrib.admin import helpers
from django.contrib.admin.util import (lookup_field,
display_for_field, label_for_field, help_text_for_field)
from django.core.exceptions import ObjectDoesNotExist
from django.db.models.fields.related import ManyToManyRel
from django.forms.util import flatatt
from django.template.defaultfilters import capfirst
from django.utils.encoding import force_unicode, smart_unicode
from django.utils.html import escape, conditional_escape
from django.utils.safestring import mark_safe
class BetterAdminReadonlyField(object):
def __init__(self, form, field, is_first, model_admin=None):
label = label_for_field(field, form._meta.model, model_admin)
# Make self.field look a little bit like a field. This means that
# {{ field.name }} must be a useful class name to identify the field.
# For convenience, store other field-related data here too.
if callable(field):
class_name = field.__name__ != '<lambda>' and field.__name__ or ''
else:
class_name = field
self.field = {
'name': class_name,
'label': label,
'field': field,
'help_text': help_text_for_field(class_name, form._meta.model)
}
self.form = form
self.model_admin = model_admin
self.is_first = is_first
self.is_checkbox = False
self.is_readonly = True
def label_tag(self):
attrs = {}
if not self.is_first:
attrs["class"] = "inline"
label = self.field['label']
contents = capfirst(force_unicode(escape(label))) + u":"
return mark_safe('<label%(attrs)s>%(contents)s</label>' % {
"attrs": flatatt(attrs),
"contents": contents,
})
def contents(self):
from django.contrib.admin.templatetags.admin_list import _boolean_icon
from django.contrib.admin.views.main import EMPTY_CHANGELIST_VALUE
field, obj, model_admin = self.field['field'], self.form.instance, self.model_admin
try:
f, attr, value = lookup_field(field, obj, model_admin)
except (AttributeError, ValueError, ObjectDoesNotExist):
result_repr = EMPTY_CHANGELIST_VALUE
else:
if f is None:
boolean = getattr(attr, "boolean", False)
if boolean:
result_repr = _boolean_icon(value)
else:
result_repr = smart_unicode(value)
if getattr(attr, "allow_tags", False):
result_repr = mark_safe(result_repr)
else:
if value is None:
result_repr = EMPTY_CHANGELIST_VALUE
elif isinstance(f.rel, ManyToManyRel):
result_repr = ", ".join(map(unicode, value.all()))
else:
result_repr = display_for_field(value, f)
return conditional_escape(result_repr)
helpers.AdminReadonlyField = BetterAdminReadonlyField
你可以把這個文件夾中的 「monkeypatches」,並稱之爲 「admin_readonly_field.py」(不要忘了還添加一個空的__init__.py
使該文件夾成爲一個模塊)。 然後在你的應用程序的__init__.py
添加
from monkeypatches import admin_readonly_field
和你離開。
上面的代碼只包含相關的導入和代碼monkeypatch AdminReadonlyField(在這種情況下從Django 1.3複製)。沒有什麼實際上改變了原來的課程。改變你在你的情況下最有用的東西。
你的具體情況,你可以,也許這兩行添加到第二個最後一個:
result_repr = display_for_field(value, f)
if isinstance(field, models.TextField):
result_repr = result_repr.replace('\n', '<br />')
(和from django.db import models
在頂部)
我很抱歉,但該類附帶的Django如此糟糕,選項2是我推薦的方式。您的文本字段是不是唯一的領域,看起來以只讀模式不好......
我喜歡重寫管理域來改變顯示的想法。從我+1。 –
jQuery的第一個選擇提出了一個期望,即'ModelAdmin.readonly_fields'中列出的字段在呈現時自動獲得'readonly' css類。這似乎並不是這樣,至少在我使用的Django版本中(1.4.3)。 –
只是意識到你正在使用grappelli。我希望有一種比覆蓋模板更簡單的方法,或者將整個野獸進行修飾。基本上我只想添加一個css類,但這似乎不可能,'attrs'是硬編碼的。我想知道爲什麼Django不使用(剝離)小部件。 –
我還在使用django 1.3,最後想出了一個解決方案。因此,如果其他人仍然在這艘船上:
覆蓋模板fieldset.html(從pythondir/djangodir/django/contrib/admin/templates/admin/includes/fieldset.html複製到djangoprojectdir/templates/admin /包括/ fieldset.html)
它包含行:
{% if field.is_readonly %}
<p>{{ field.contents }}</p>
他們更改爲:
{% if field.is_readonly %}
<p>{{ field.contents|linebreaksbr }}</p>
這是試圖丹尼的解決方案結束後翅因爲從內容函數返回的文本被轉義以替換具有轉義碼的標籤(「<」等),然後閱讀以下內容:https://code.djangoproject.com/ticket/19226。
- 1. 使用letterings.js保留文本的格式
- 2. 動態設置django中的readonly_fields admin
- 3. 文本框中的文本不保留其格式
- 4. 如何在JavaScript中保留getElementById的文本格式?
- 5. 提取文本和保留格式
- 6. 如何在XSL中調用模板時保留文本格式?
- 7. 如何格式化TextField的文本? JavaFX
- 8. Django的使用readonly_fields
- 9. textfield中的文本
- 10. 如何從richTextbox中讀取文本並保留文本的格式?
- 11. 爲未來版本保留django-admin更改的最佳方式?
- 12. 如何保留textarea表單文章中的空格和格式?
- 13. 將文本保留在表格單元格的中心底部
- 14. 如何在多行文本框中保留格式
- 15. 如何在OpenXML中使用格式保留字符串段落,運行,文本?
- 16. 在ActionScript 3.0中更改TextField的文本格式
- 17. 在使用JavaScript/HTML處理後保留文本文檔的格式
- 18. 結合保留分隔符和格式的文本文件
- 19. ios中textfield中的十進制格式
- 20. 驗證TextField中的文本
- 21. 如何使用XSL-FO保留格式(保留CR-LF字符)?
- 22. Excel中使用VBA的文本格式
- 23. 明確格的內容,但保留純文本,使用jQuery
- 24. 如何在UIAlertController中的塊中使用TextField中的文本?
- 25. 使用Crypto ++格式保留加密
- 26. 在文本文件中保留以模式開頭的行
- 27. 如何在dateWithTimeIntervalSince1970中使用TextField文本?
- 28. 如何使用固定寬度格式化文本時保留空格?
- 29. 用c#保存XML文件並保留空元素的格式
- 30. 在UITextField中保留文本的視圖
如果你保存br標籤(它改變了數據),標準textarea不再有換行符,並且像django-tinymce這樣的編輯器變得更加必要。如果你需要真正的換行符,你在另一個方向上面臨同樣的問題... –
是的,這是一個很好的觀點。我認爲解決方案實際上取決於數據的用途。 –
感謝您的答案,但txt文件的內容是由自定義命令編寫的。使用JavaScript也失敗了。任何其他想法?謝謝! – LinuxMan