2015-09-14 10 views
7

क्या इसके दो स्तंभों के एक संयोजन का उपयोग करके मॉडल फ़िल्टर करने का कोई तरीका है?दो स्तंभों के एक संयोजन के बाद Django क्वेरीसेट फ़िल्टर

class Item(models.Model): 
    series = models.CharField(max_length=50) 
    number = models.CharField(max_length=50) 

क्या मैं जरूरत है दो स्तंभों के संयोजन के बाद फिल्टर करने के लिए, यदि कोई उपयोगकर्ता आदानों A123 मैं किसी भी आइटम% एक तरह श्रृंखला और नंबर है कि खोजने के लिए सक्षम होना चाहते हैं और: मेरा मॉडल इस तरह है 123% या% ए 1 और 23% क्या यह django मॉडल का उपयोग कर संभव है? या कच्चे एसक्यूएल के साथ यह संभव है? मैं संगतता के साथ एक नया स्तंभ नहीं बनाऊंगा।

उत्तर

12

हां यह संभव है; आपको फ़ील्ड के समामेलन के साथ QuerySet annotate की आवश्यकता होगी, और वह नया "वर्चुअल" कॉलम फ़िल्टर करने में सक्षम होगा।

relevant documentation on filtering annotations

using Concat as an annotation function

+0

जवाब के लिए धन्यवाद उपयोग कर रहा है, दुर्भाग्य से मैं Django 1.3 उपयोग कर रहा हूँ इसलिए कोई Concat परिभाषित किया गया है। मैंने इसे यहां वर्णित करने की कोशिश की: http://stackoverflow.com/questions/4348124/django-orm-filter-by-extra-attribute/4348728#4348728 लेकिन मुझे कुछ त्रुटियां मिलती हैं और मैं इसे भी ऐसा करने में थक गया : चालान = invoices.extra ( जहां = [ 'concat (document_series_name, document_number) की तरह "% F001%"'], ) लेकिन मैं एक ही मिली त्रुटियाँ मिल गया: सीमा से बाहर टपल सूचकांक /usr/स्थानीय/lib/python2.7/dist-packages/django/db/backends/postgresql_psycopg2/exec.py निष्पादित करें, लाइन 44 –

+1

वैसे यह एक संस्करण संख्या है जिसे मैंने थोड़ी देर में नहीं सुना है ... दस्तावेज़ अब और भी उपलब्ध नहीं है ! मुझे लगता है कि आप किसी भी कारण से अपग्रेड नहीं कर सकते हैं - भले ही आपको वास्तव में सुरक्षा कारणों से कम से कम करना चाहिए। वैसे भी, आपकी सबसे अच्छी शर्त शायद कच्चे एसक्यूएल लिख रही है, शायद जांचें कि 'एफ()' एक्सप्रेशन फिर भी उपलब्ध थे या नहीं। – mccc

+0

धन्यवाद, मैं कोशिश करूंगा, उत्तर अभी भी मान्य है, धन्यवाद –

9

क्या पहले, उदाहरण के कहा गया था के अलावा:

from django.db.models import Value 
from django.db.models.functions import Concat 
queryset = Item.objects.annotate(search_name=Concat('series', Value(' '), 'number')) 
# then you can filter: 
queryset.filter(search_name__icontains='whatever text') 
+0

"मूल्य" क्या है? – Mojimi

+0

यह एक ऐसा फ़ंक्शन है जिसका उपयोग आपको उपयोग करने की आवश्यकता है यदि आप कॉलम नाम की बजाय वास्तविक स्ट्रिंग का उपयोग करना चाहते हैं – mccc

0

यहाँ एक पूर्ण उदाहरण annotate() function और एक 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 

NAME = 'udjango' 


def main(): 
    setup() 

    class Item(models.Model): 
     series = models.CharField(max_length=50) 
     number = models.CharField(max_length=50) 

    syncdb(Item) 

    Item.objects.create(series='A', number='1234') 
    Item.objects.create(series='A', number='1230') 
    Item.objects.create(series='A', number='9999') 
    Item.objects.create(series='B', number='1234') 

    print(Item.objects.annotate(
     search=Concat('series', 'number')).filter(
      search__icontains='A123').values_list('series', 'number')) 
    # >>> [(u'A', u'1234'), (u'A', u'1230')] 


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() 
2

अगर आप वाला उपयोग ajax अनुरोध में से कुछ हैं मैं अपने रास्ता मिल गया,, तो मैं views.py

AllUser = User.objects.all() 
users = [] 
for i in AllUser: 
    if query in i.get_full_name(): 
     users += [{'first_name':i.first_name,'last_name':i.last_name,'full_name':i.get_full_name()}] 

qUser = users 

में और लौट आए ajax पृष्ठ में इस

की तरह उपयोग करने के लिए शुरू कर दिया (मेरे मामले 'searchajax.html')

{% if qUser %} 
    {% for i in qUser %} 
    <p class="queryP">{{ i.full_name }}</p> 
    {% endfor %} 
{% endif %} 

यह मेरे लिए बहुत अच्छी तरह से काम करता है :)) में

एक और तरीका है व्याख्या

from django.db.models import CharField, Value as V 
from django.db.models.functions import Concat 
author = User.objects.annotate(screen_name=Concat('first_name', V(' ') ,'last_name')) 
for i in author: 
    print i.screen_name 

यह एक ही काम भी करता है :))

संबंधित मुद्दे