Django: values_list() multiple fields concatenated
我有一个
我正在尝试使用
1 | data.form.fields['person'].choices = GetPersons().values_list('id', 'first_name') |
1 | return Person.objects.filter(id__gt=1000)` |
例如
,所以我只会吸引我想露面的人。如何使用
我为您准备了2个建议:
- 第一个方法是使用extra来连接数据库中的字段。对我来说是一个肮脏的解决方案,但可以运行。
样品:
1 2 | persons = GetPersons().extra(select={'full_name':"concatenate( first, last)"} ) choices = persons.values_list('id', 'full_name') |
和...
- 第二个使用列表理解:
样品:
1 | choices = [ ( p.id, '{0} {1}'.format( p.first, p.last ),) for p in GetPersons() ] |
2018年编辑
Concat现在可用作数据库功能:
1 2 3 4 5 6 7 8 | >>> from django.db.models import CharField, Value as V >>> from django.db.models.functions import Concat >>> persons = GetPersons().annotate( ... full_name=Concat( ... 'last', V(', '), 'first', V('.'), ... output_field=CharField() ... ) ... ) |
听起来
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | # Tested with Django 1.9.2 import sys import django from django.apps import apps from django.apps.config import AppConfig from django.conf import settings from django.db import connections, models, DEFAULT_DB_ALIAS from django.db.models.base import ModelBase from django.db.models.functions import Concat, Value NAME = 'udjango' def main(): setup() class Person(models.Model): first_name = models.CharField(max_length=30) last_name = models.CharField(max_length=30) syncdb(Person) Person.objects.create(first_name='Jimmy', last_name='Jones') Person.objects.create(first_name='Bob', last_name='Brown') print(Person.objects.annotate( full_name=Concat('first_name', Value(' '), 'last_name')).values_list('id', 'full_name')) # >>> [(1, u'Jimmy Jones'), (2, u'Bob Brown')] def setup(): DB_FILE = NAME + '.db' with open(DB_FILE, 'w'): pass # wipe the database settings.configure( DEBUG=True, DATABASES={ DEFAULT_DB_ALIAS: { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': DB_FILE}}, LOGGING={'version': 1, 'disable_existing_loggers': False, 'formatters': { 'debug': { 'format': '%(asctime)s[%(levelname)s]' '%(name)s.%(funcName)s(): %(message)s', 'datefmt': '%Y-%m-%d %H:%M:%S'}}, 'handlers': { 'console': { 'level': 'DEBUG', 'class': 'logging.StreamHandler', 'formatter': 'debug'}}, 'root': { 'handlers': ['console'], 'level': 'WARN'}, 'loggers': { "django.db": {"level":"WARN"}}}) app_config = AppConfig(NAME, sys.modules['__main__']) apps.populate([app_config]) django.setup() original_new_func = ModelBase.__new__ @staticmethod def patched_new(cls, name, bases, attrs): if 'Meta' not in attrs: class Meta: app_label = NAME attrs['Meta'] = Meta return original_new_func(cls, name, bases, attrs) ModelBase.__new__ = patched_new def syncdb(model): """ Standard syncdb expects models to be in reliable locations. Based on https://github.com/django/django/blob/1.9.3 /django/core/management/commands/migrate.py#L285 """ connection = connections[DEFAULT_DB_ALIAS] with connection.schema_editor() as editor: editor.create_model(model) main() |
Per:是否可以使用Django的QuerySet.values_list来引用属性,在不适用时避免使用values_list,而是使用理解。
1 2 3 4 5 6 7 8 9 | models.py: class Person(models.Model): first_name = models.CharField(max_length=32) last_name = models.CharField(max_length=64) def getPrintName(self): return self.last_name +"," + self.first_name views.py: data.form.fields['person'].choices = [(person.id, person.getPrintName()) for person in GetPersons()] |