2012-07-10 2 views
9

나는 Person 모델을 가지고 있고 django 양식을 사용하여 외래 키가있는 다른 개체를 Person으로 편집하고 있습니다. 사람 모델의 필드는 first_namelast_name입니다. 외국 참조 드롭 다운 상자에 대한 결과를 필터링하는 메서드를 실행하고 싶습니다.Django : values_list() 여러 필드를 연결

나는 (선택 속성)과 같이 양식 필드 옵션을 재정의 할 values_list()를 사용하는 것을 시도하고있다 :

data.form.fields['person'].choices = GetPersons().values_list('id', 'first_name') 

GetPersons() 그냥 예를 들어

return Person.objects.filter(id__gt=1000)` 

같은 Person 클래스를 필터링, 그래서 단지 I 내가 보여주고 싶은 사람들을 만나. 사전을 반환하고 모든 것을 수동으로 분할 할 필요없이 values_list()을 사용하여 first_namelast_name의 연결을 반환하려면 어떻게해야합니까?

답변

11

나는 당신을 위해 염두에 둘 sugestions 있습니다

  • 첫 번째 extra와 데이터베이스 필드를 연결하는 것입니다. 나를 위해 더러운 솔루션이지만 실행할 수 있습니다.

샘플 :

persons = GetPersons().extra(select={'full_name': "concatenate(first, last) "}) 
choices = persons.values_list('id', 'full_name') 

및 ...

  • 두 번째 사용 지능형리스트 :

샘플 :

choices = [ (p.id, '{0} {1}'.format(p.first, p.last),) for p in GetPersons() ] 
+0

감사합니다. @danihp, 저는 이해력을 사용하고 답을 수락합니다. – Furbeenator

0

Per : Is it possible to reference a property using Django's QuerySet.values_list?, 적용 할 수없는 경우 values_list를 사용하지 말고 이해력을 사용하십시오.

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()] 
5

annotate() function이 Django 1.8에서 더 유연해진 것처럼 들립니다. 두 필드를 Concat expression과 결합한 다음 쿼리 세트에 해당 표현식을 사용하여 주석을 달 수 있습니다.

# 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() 
+0

그것, 좋은 해결책을위한 감사합니다! 나는 이것이 받아 들여진 대답보다 일반적으로 지원되는 방법이라고 생각하겠습니까? – Gesias

+0

모든 장고 백엔드 @Gesias에서 지원한다고 가정합니다. 예를 들어, Sqlite3에서 허용되는 응답이'||'연산자와 연결되어 있기 때문에 받아 들일 수있는 대답이 아니라고 생각합니다. 공정하게, 나는 그것을 시도하지 않았다. –

+0

좋은 답변입니다! 이 과정에서 형식을 변환하는 방법에 대해 알고 있습니까? 예를 들어, id를 문자열로 변환하고 이름과 연결하려면 어떻게해야합니까? –

관련 문제