django-models - Django:أي ما يعادل "حدد[اسم العمود]من[tablename]"




(4)

وبطبيعة الحال ، ستقوم values و values_list باسترداد القيم الأولية من قاعدة البيانات. لا يستطيع Django أن يعمل "السحر" الخاص به على نموذج ما يعني أنك لن تتمكن من اجتياز العلاقات لأنك عالق بالمعرف الذي يشير إليه المفتاح الخارجي ، بدلاً من حقل ForeignKey.

إذا كنت تريد تصفية هذه القيم ، فيمكنك القيام بما يلي (على افتراض أن column_name عبارة عن ForeignKey يشير إلى MyModel ):

ids = Entry.objects.values_list('column_name', flat=True).filter(...)
my_models = MyModel.objects.filter(pk__in=set(ids))

إليك وثائق لـ values_list()

أردت أن أعرف هل هناك أي شيء يعادل:

select columnname from tablename

مثل يقول جانغو البرنامج التعليمي:

Entry.objects.filter(condition)

يجلب كل الكائنات مع الشرط المحدد. إنه يشبه:

select * from Entry where condition

لكنني أرغب في إنشاء قائمة بعمود واحد فقط (وهو في حالتي مفتاح خارجي). وجدت ذلك:

Entry.objects.values_list('column_name', flat=True).filter(condition)

يفعل الشيء نفسه. ولكن في حالتي ، العمود هو مفتاح خارجي ، ويفقد هذا الاستعلام خاصية مفتاح خارجي. انها مجرد تخزين القيم. لا أستطيع إجراء مكالمات البحث.


لتقييد تعيين استعلام على عمود (أعمدة) محدد تستخدم القيم. (العمود)

من المحتمل أيضًا أن تضيف تمييزًا مميزًا حتى النهاية ، بحيث ينتهي بحثك:

Entry.objects.filter(myfilter).values(columname).distinct()

انظر: https://docs.djangoproject.com/en/dev/ref/models/querysets/#django.db.models.query.QuerySet.values

للمزيد من المعلومات

اعتمادا على إجابتك في التعليق ، سوف أعود وتحرير.

تصحيح:

لست متأكدا إذا كان النهج الصحيح واحد رغم ذلك. يمكنك الحصول على جميع الكائنات الخاصة بك في قائمة python عن طريق الحصول على queryset عادي عبر عامل تصفية ثم القيام بما يلي:

myobjectlist = map(lambda x: x.mycolumnname, myqueryset)

المشكلة الوحيدة في هذا النهج هي إذا كان طلب البحث الخاص بك كبيرًا ، فسيكون استخدامك للذاكرة كبيرًا بنفس القدر.

على أي حال ، ما زلت غير متأكد من بعض تفاصيل المشكلة.


لديك نموذج A مع مفتاح خارجي إلى طراز آخر B ، وتريد تحديد B s التي يشار إليها ببعض A هل هذا صحيح؟ إذا كان الأمر كذلك ، فإن طلب البحث هو فقط:

B.objects.filter(a__isnull = False)

إذا كانت لديك شروط على A ، فيمكن أن يكون الاستعلام:

B.objects.filter(a__field1 = value1, a__field2 = value2, ...)

راجع وثائق العلاقات العكسية لـ Django للحصول على توضيح لماذا يعمل هذا ، وخيار ForeignKey.related_name إذا كنت ترغب في تغيير اسم العلاقة إلى الوراء.


أنا حاليا باستخدام هذا الرمز في وحدة s3utils منفصلة:

from django.core.exceptions import SuspiciousOperation
from django.utils.encoding import force_unicode

from storages.backends.s3boto import S3BotoStorage


def safe_join(base, *paths):
    """
    A version of django.utils._os.safe_join for S3 paths.

    Joins one or more path components to the base path component intelligently.
    Returns a normalized version of the final path.

    The final path must be located inside of the base path component (otherwise
    a ValueError is raised).

    Paths outside the base path indicate a possible security sensitive operation.
    """
    from urlparse import urljoin
    base_path = force_unicode(base)
    paths = map(lambda p: force_unicode(p), paths)
    final_path = urljoin(base_path + ("/" if not base_path.endswith("/") else ""), *paths)
    # Ensure final_path starts with base_path and that the next character after
    # the final path is '/' (or nothing, in which case final_path must be
    # equal to base_path).
    base_path_len = len(base_path) - 1
    if not final_path.startswith(base_path) \
       or final_path[base_path_len:base_path_len + 1] not in ('', '/'):
        raise ValueError('the joined path is located outside of the base path'
                         ' component')
    return final_path


class StaticRootS3BotoStorage(S3BotoStorage):
    def __init__(self, *args, **kwargs):
        super(StaticRootS3BotoStorage, self).__init__(*args, **kwargs)
        self.location = kwargs.get('location', '')
        self.location = 'static/' + self.location.lstrip('/')

    def _normalize_name(self, name):
        try:
            return safe_join(self.location, name).lstrip('/')
        except ValueError:
            raise SuspiciousOperation("Attempted access to '%s' denied." % name)


class MediaRootS3BotoStorage(S3BotoStorage):
    def __init__(self, *args, **kwargs):
        super(MediaRootS3BotoStorage, self).__init__(*args, **kwargs)
        self.location = kwargs.get('location', '')
        self.location = 'media/' + self.location.lstrip('/')

    def _normalize_name(self, name):
        try:
            return safe_join(self.location, name).lstrip('/')
        except ValueError:
            raise SuspiciousOperation("Attempted access to '%s' denied." % name)

ثم ، في وحدة الإعدادات الخاصة بي:

DEFAULT_FILE_STORAGE = 'myproyect.s3utils.MediaRootS3BotoStorage'
STATICFILES_STORAGE = 'myproyect.s3utils.StaticRootS3BotoStorage'

حصلت على إعادة تعريف طريقة خاصة _normalize_name() لاستخدام إصدار "ثابت" safe_join() ، لأن الرمز الأصلي يعطيني استثناءات SuspiciousOperation للمسارات القانونية.

أنا نشر هذا للنظر ، إذا كان أي شخص يمكن أن يعطي إجابة أفضل أو تحسين هذا واحد ، سيكون موضع ترحيب كبير.





django django-models