จัดรูปแบบตัวเลขในเทมเพลต django


153

ฉันพยายามจัดรูปแบบตัวเลข ตัวอย่าง:

1     => 1
12    => 12
123   => 123
1234  => 1,234
12345 => 12,345

มันเป็นเรื่องธรรมดาพอสมควรที่จะทำ แต่ฉันไม่สามารถเข้าใจได้ว่าฉันควรใช้ตัวกรองแบบใด

แก้ไข: ถ้าคุณใช้วิธีการแบบ Python ทั่วไปฉันยินดีที่จะเพิ่มเขตข้อมูลที่จัดรูปแบบในแบบจำลองของฉัน


3
ระวังหากผู้ใช้เป้าหมายของคุณอยู่ในยุโรปด้วย บางประเทศในยุโรปเช่นเยอรมนีใช้เป็นเครื่องหมายทศนิยม
tobltobs

คำตอบ:


313

แอปพลิเคชั่นhumanize ที่มีส่วนร่วมของ Django ทำสิ่งนี้

{% load humanize %}
{{ my_num|intcomma }}

อย่าลืมเพิ่มลง'django.contrib.humanize'ในINSTALLED_APPSรายการของคุณในsettings.pyไฟล์


17
มีเหตุผลว่าทำไมตัวกรองแบบง่าย ๆ เหล่านี้ไม่ได้เป็นส่วนหนึ่งของตัวกรองในตัวหรือไม่
PawelRoman

8
@PawelRoman เพื่อหลีกเลี่ยงการโหลดตัวกรองจำนวนมากและแท็กที่ไม่ค่อยได้ใช้ (และทำให้เทมเพลตเร็วขึ้น)
Maxime Lorant

ฉันได้เพิ่ม 'django.contrib.humanize' ใน INSTALLED_APPS และรวม {% load humanize%} ในเทมเพลตของฉันด้วยและรีสตาร์ทเซิร์ฟเวอร์ อย่างไรก็ตามเมื่อฉันพยายามใช้ตัวกรอง "intcomma" ฉันได้รับข้อผิดพลาดนี้ - ตัวกรองไม่ถูกต้อง: 'intcomma' การติดตามการดีบักจะแสดง 'django.contrib.humanize' รวมอยู่ใน settings.py ปัญหาที่อาจเป็นไปได้คืออะไร
Manish

1
รับคำตอบสำหรับปัญหาของฉันที่นี่ - ฉันได้รวม {% load humanize%} ไว้ในเทมเพลตฐาน (เนื่องจากฉันต้องการเทมเพลตจำนวนมาก) ดูเหมือนว่ามันจะไม่ทำงาน - เมื่อฉันเพิ่มลงในเทมเพลตที่เกี่ยวข้องมันใช้งานได้ดี! :-)
Manish

หากไม่สามารถใช้งานได้อาจเป็นเพราะการแปลภาษาท้องถิ่น ลอง {{my_num | intcomma: False}} ในกรณีนี้
Jose Cherian

105

จากคำตอบอื่น ๆ เพื่อขยายสิ่งนี้ให้ลอยคุณสามารถทำสิ่งต่อไปนี้

{% load humanize %}
{{ floatvalue|floatformat:2|intcomma }}

เอกสาร: floatformat, intcomma.


59

เกี่ยวกับโซลูชันของ Ned Batchelder นี่คือทศนิยม 2 ตำแหน่งและเครื่องหมายดอลลาร์ นี่ไปที่ไหนซักอย่างmy_app/templatetags/my_filters.py

from django import template
from django.contrib.humanize.templatetags.humanize import intcomma

register = template.Library()

def currency(dollars):
    dollars = round(float(dollars), 2)
    return "$%s%s" % (intcomma(int(dollars)), ("%0.2f" % dollars)[-3:])

register.filter('currency', currency)

จากนั้นคุณสามารถ

{% load my_filters %}
{{my_dollars | currency}}

3
บั๊กของโค้ดด้านบนให้ลองสิ่งนี้:>>> currency(0.99958) u'$0.00'
Ahsan

1
รหัสนี้ควรอยู่ในไฟล์ของตนเองที่ [your_project] / [your_app] / templatetags / [filtername] .py จากนั้นควรโหลดในเทมเพลตที่มี {% load [filtername]%} ดูdocs.djangoproject.com/en/1.10/howto/custom-template-tagsสำหรับข้อมูลที่เป็นประโยชน์และเฉพาะเจาะจงมากขึ้น
อันยิ่งใหญ่

20

ลองเพิ่มบรรทัดต่อไปนี้ใน settings.py:

USE_THOUSAND_SEPARATOR = True

สิ่งนี้น่าจะใช้ได้

อ้างถึงเอกสาร


อัปเดตที่ 2018-04-16:

นอกจากนี้ยังมีวิธีการที่หลามในการทำสิ่งนี้:

>>> '{:,}'.format(1000000)
'1,000,000'

10
ระวังเมื่อใช้สิ่งนี้ จะจัดรูปแบบตัวเลขใน URL และอื่น ๆ ที่คุณเพิ่มไปยังเทมเพลต
Christoffer

4
ฉันไม่สามารถเน้นความคิดเห็นของ @Christoffer ได้มากพอ - ในเทมเพลตที่มีการแสดงผลและใช้ ID ในลิงก์ซึ่งอาจทำให้เกิดอาการปวดหัวที่สำคัญ!
LaundroMat

สิ่งนี้ไม่เหมาะสมสำหรับเทมเพลต Django
Ben

@Ben ไหนไม่เหมาะสม? "ทางหลาม" หรือการตั้งค่าสถานะตัวคั่นหลักพันในการตั้งค่า? ธงตัวคั่นหลักพันควรทำงานได้ดีสำหรับแม่แบบ Django รุ่นของคุณ Django คืออะไร?
carton.swing

1
รูปแบบสตริง (ไพ ธ อน) เพราะคุณไม่สามารถใช้สิ่งนี้ได้โดยตรงในเทมเพลต - คุณต้องใส่เทมเพลตนี้ลงในเทมเพลตแท็ก (ซึ่งเป็นคำตอบที่ดี) แต่การทิ้งสิ่งนี้เป็นการใช้คำตอบเพียงเล็กน้อย
Ben

11

หากคุณไม่ต้องการมีส่วนร่วมกับโลแคลที่นี่เป็นฟังก์ชันที่จัดรูปแบบตัวเลข:

def int_format(value, decimal_points=3, seperator=u'.'):
    value = str(value)
    if len(value) <= decimal_points:
        return value
    # say here we have value = '12345' and the default params above
    parts = []
    while value:
        parts.append(value[-decimal_points:])
        value = value[:-decimal_points]
    # now we should have parts = ['345', '12']
    parts.reverse()
    # and the return value should be u'12.345'
    return seperator.join(parts)

การสร้างตัวกรองแม่แบบกำหนดเองจากฟังก์ชั่นนี้เป็นเรื่องเล็กน้อย


10

เมตตาแก้ปัญหาคือดีถ้าเว็บไซต์ของคุณในภาษาอังกฤษ สำหรับภาษาอื่น ๆ ที่คุณต้องแก้ไขปัญหาอื่น: ผมขอแนะนำให้ใช้Babel ทางออกหนึ่งคือการสร้างแท็กแม่แบบกำหนดเองเพื่อแสดงหมายเลขอย่างถูกต้อง นี่คือวิธี: เพียงสร้างไฟล์ต่อไปนี้ในyour_project/your_app/templatetags/sexify.py:

# -*- coding: utf-8 -*-
from django import template
from django.utils.translation import to_locale, get_language
from babel.numbers import format_number

register = template.Library()

def sexy_number(context, number, locale = None):
    if locale is None:
        locale = to_locale(get_language())
    return format_number(number, locale = locale)

register.simple_tag(takes_context=True)(sexy_number)

จากนั้นคุณสามารถใช้เทมเพลตแท็กนี้ในเทมเพลตของคุณดังนี้:

{% load sexy_number from sexify %}

{% sexy_number 1234.56 %}
  • สำหรับผู้ใช้ชาวอเมริกัน (locale en_US) แสดงเป็น 1,234.56
  • สำหรับผู้ใช้ภาษาฝรั่งเศส (locale fr_FR) จะแสดง 1 234,56
  • ...

แน่นอนคุณสามารถใช้ตัวแปรแทน:

{% sexy_number some_variable %}

หมายเหตุ:contextพารามิเตอร์ในปัจจุบันไม่ได้ใช้ในตัวอย่างของฉัน แต่ฉันทำให้มันมีการแสดงให้เห็นว่าคุณสามารถปรับแต่งแท็กแม่แบบนี้จะทำให้มันใช้อะไรว่าในบริบทแม่แบบ


1
สถานที่ของฉันคือ 'pt_BR' และ "intcomma" ทำงานได้แม้ในบราซิลที่แยกออกจาก '.' และไม่ใช่โดย ',' being floatvalue = 25000.35 {{floatvalue | intcomma}} ผลลัพธ์ใน 25000.35
Zokis

คุณพูดถูก แต่รูปแบบนี้ไม่เหมาะสมกับตัวคั่นหลักพัน (25,000.35 สำหรับ en_US และ 25 000,35 สำหรับ fr_FR)
MiniQuark

4

แอปเมตตาข้อเสนอที่ดีและเป็นวิธีที่รวดเร็วของการจัดรูปแบบตัวเลข แต่ถ้าคุณต้องการที่จะใช้ที่แตกต่างกันแยกจากจุลภาคก็ง่ายเพียงแค่นำมาใช้รหัสจากการตรวจสอบมีเมตตากรุณาที่เปลี่ยนถ่านคั่นและสร้างตัวกรองที่กำหนดเอง ตัวอย่างเช่นใช้พื้นที่เป็นตัวคั่น:

@register.filter('intspace')
def intspace(value):
    """
    Converts an integer to a string containing spaces every three digits.
    For example, 3000 becomes '3 000' and 45000 becomes '45 000'.
    See django.contrib.humanize app
    """
    orig = force_unicode(value)
    new = re.sub("^(-?\d+)(\d{3})", '\g<1> \g<2>', orig)
    if orig == new:
        return new
    else:
        return intspace(new)

ขอบคุณ ฉันต้องการรุ่นดอทและข้อเสนอแนะของคุณช่วยฉันได้! ไชโย!
kstratis

3

ปิดหัวข้อเล็กน้อย:

ฉันพบคำถามนี้ขณะมองหาวิธีจัดรูปแบบตัวเลขเป็นสกุลเงินเช่น:

$100
($50)  # negative numbers without '-' and in parens

ฉันลงเอยด้วยการทำ:

{% if   var >= 0 %} ${{ var|stringformat:"d" }}
{% elif var <  0 %} $({{ var|stringformat:"d"|cut:"-" }})
{% endif %}

คุณสามารถทำได้เช่น{{ var|stringformat:"1.2f"|cut:"-" }}เพื่อแสดงเป็น$50.00(ที่มีทศนิยม 2 ตำแหน่งหากนั่นคือสิ่งที่คุณต้องการ

อาจจะเล็กน้อยในด้านแฮ็ค แต่อาจมีคนอื่นเห็นว่ามีประโยชน์


2

ฉันไม่สามารถหาวิธี Django แต่ฉันพบวิธีหลามจากภายในโมเดลของฉัน:

def format_price(self):
    import locale
    locale.setlocale(locale.LC_ALL, '')
    return locale.format('%d', self.price, True)

อืม - นี่เป็น -1 แล้วโดยไม่มีคำอธิบาย - ไม่ช่วยเหลือ สำหรับผู้ที่คิดว่าคำตอบนั้นไม่ถูกต้องโปรดบอกว่าทำไมเพื่อประโยชน์ของผู้ตอบและผู้อ่าน ฉันคิดว่าฉันไม่ใช่แฟนของการตั้งค่าสถานที่ (ซึ่งเป็นสากลในการเข้าถึง) ในฟังก์ชั่นนี้ (ด้านที่ไม่พึงประสงค์ส่งผลกระทบต่อการรับสกุลเงิน) - ซึ่งสามารถอธิบาย -1
Danny Staple

ฉันทำที่สอง -1 - ตามที่อธิบายไว้ก่อนหน้า ความคิดเห็นมันs really not correct not giving any reason. Here itง่าย: Django มีเทมเพลตเฉพาะ (คล้ายกับ Jinja2 - หรือมันคือ Jinja2) ซึ่งไม่อนุญาตให้ใช้ฟังก์ชั่นหลามแบบมาตรฐาน ดังนั้นคำตอบนี้ไม่เป็นประโยชน์เลย อะไรคือสิ่งที่ Django ได้มีฟังก์ชั่นของตัวเองในการจัดการนี้และ writting สิ่งใหม่สิ่งที่ทำงานมันไม่คิดที่ดี ...
Tomis

2
ฉันไม่เห็นด้วยกับ downvoters - ตรวจสอบให้แน่ใจว่าค่านั้นได้รับการจัดรูปแบบอย่างถูกต้องในฟังก์ชั่นมุมมองก่อนที่จะฮิตเทมเพลตดูเหมือนว่าเป็นวิธีการที่สมบูรณ์แบบ
พอลทอมบลิน

1

โปรดทราบว่าการเปลี่ยนสถานที่เกิดเหตุนั้นครอบคลุมทั้งกระบวนการและไม่ปลอดภัยต่อเธรด (iow. สามารถมีผลข้างเคียงหรืออาจส่งผลต่อรหัสอื่น ๆ ที่ดำเนินการภายในกระบวนการเดียวกัน)

ข้อเสนอของฉัน: ตรวจสอบแพ็คเกจBabel มีบางวิธีในการรวมเข้ากับเทมเพลต Django



1

จากคำตอบ muhuk ฉันได้ทำวิธีง่ายๆในการห่อหุ้มแท็กไพstring.formatธ อน

  • สร้างtemplatetagsโฟลเดอร์แอปพลิเคชันของคุณ
  • สร้างformat.pyไฟล์ขึ้นมา
  • เพิ่มไปยังมัน:

    from django import template
    
    register = template.Library()
    
    @register.filter(name='format')
    def format(value, fmt):
        return fmt.format(value)
  • โหลดไว้ในเทมเพลตของคุณ {% load format %}
  • ใช้มัน. {{ some_value|format:"{:0.2f}" }}

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.