Получение данных из базы данных с помощью Python (на платформе Django) - PullRequest
0 голосов
/ 02 декабря 2009

Обычно, если бы я написал SQL-заявление для этого, я бы сделал что-то вроде этого,

    SELECT * FROM (django_baseaccount LEFT JOIN django_account ON django_baseaccount.user_id = django_account.baseaccount_ptr_id)
LEFT JOIN django_address ON django_account.baseaccount_ptr_id = django_address.user_id;name 

как мне это сделать в способе Djagno для запросов к базе данных с помощью API, т.е.

TradeDownloads.objects.filter(online=1)[:6]

Мои модели ОСНОВНОЙ СЧЕТ

class BaseAccount(models.Model):
user = models.ForeignKey(User, unique=True)

def __unicode__(self):
    """
    Return the unicode representation of this customer, which is the user's
    full name, if set, otherwise, the user's username
    """
    fn = self.user.get_full_name()
    if fn:
        return fn
    return self.user.username

def user_name(self):
    """
    Returns the full name of the related user object
    """
    return self.user.get_full_name()

def email(self):
    """
    Return the email address of the related user object
    """
    return self.user.email

СЧЕТ

class Account(BaseAccount):
"""
The account is an extension of the Django user and serves as the profile
object in user.get_profile() for shop purchases and sessions
"""
telephone = models.CharField(max_length=32)
default_address = models.ForeignKey(Address, related_name='billing_account', blank=True, null=True)
security_question = models.ForeignKey(SecurityQuestion)
security_answer = models.CharField(max_length=200)
how_heard = models.CharField("How did you hear about us?", max_length=100)
feedback = models.TextField(blank=True)
opt_in = models.BooleanField("Subscribe to mailing list", help_text="Please tick here if you would like to receive updates from %s" % Site.objects.get_current().name)
temporary = models.BooleanField()

def has_placed_orders(self):
    """
    Returns True if the user has placed at least one order, False otherwise
    """
    return self.order_set.count() > 0

def get_last_order(self):
    """
    Returns the latest order that this customer has placed. If no orders
    have been placed, then None is returned
    """
    try:
        return self.order_set.all().order_by('-date')[0]
    except IndexError:
        return None

def get_currency(self):
    """
    Get the currency for this customer. If global currencies are enabled
    (settings.ENABLE_GLOBAL_CURRENCIES) then this function will return
    the currency related to their default address, otherwise, it returns
    the site default
    """
    if settings.ENABLE_GLOBAL_CURRENCIES:
        return self.default_address.country.currency
    return Currency.get_default_currency()
currency = property(get_currency)

def get_gateway_currency(self):
    """
    Get the currency that an order will be put through protx with. If protx
    currencies are enabled (settings.ENABLE_PROTX_CURRENCIES), then the
    currency will be the same returned by get_currency, otherwise, the
    site default is used
    """
    if settings.ENABLE_PROTX_CURRENCIES and settings.ENABLE_GLOBAL_CURRENCIES:
        return self.currency
    return Currency.get_default_currency()
gateway_currency = property(get_gateway_currency)

АДРЕС

class Address(models.Model):
"""
This class encapsulates the data required for postage and payment mechanisms
across the site. Each address is associated with a single store account
"""
trade_user = models.BooleanField("Are you a stockist of N  Products", help_text="Please here if you are a  Stockist")
company_name = models.CharField(max_length=32, blank=True)
line1 = models.CharField(max_length=200)
line2 = models.CharField(max_length=200, blank=True)
line3 = models.CharField(max_length=200, blank=True)
city = models.CharField(max_length=32)
county = models.CharField(max_length=32)
postcode = models.CharField(max_length=12)
country = models.ForeignKey(Country)
account = models.ForeignKey('Account')

class Meta:
    """
    Django meta options

    verbose_name_plural = "Addresses"
    """
    verbose_name_plural = "Addresses"

def __unicode__(self):
    """
    The unicode representation of this address, the postcode plus the county
    """
    return ', '.join((self.postcode, str(self.county)))

def line_list(self):
    """
    Return a list of all of this objects address lines that are not blank,
    in the natural order that you'd expect to see them. This is useful for
    outputting to a template with the aid of python String.join()
    """
    return [val for val in (self.line1, self.line2, self.line3, self.city, self.county, self.postcode, self.country.name) if val]

Ответы [ 3 ]

7 голосов
/ 02 декабря 2009

"обычно, если бы я писал SQL-заявление"

Добро пожаловать в ORM. Вы не пишете SQL, поэтому удалите это из вопроса . Никогда не публикуйте SQL и не спрашивайте, как перевести SQL в ORM. Перевод SQL ограничивает вашу способность к обучению. Хватит это делать.

Запишите, каким должен быть результат.

Похоже, вы получаете все Account объектов. Период. В какой-то момент в функции представления или шаблоне вы также хотите получить Address.

for a in Account.objects.all():
    a.default_address # this is the address that SQL brought in via a "join".

Вот и все. Пожалуйста, сделайте все примеры из учебника по Django. Фактически наберите код из примеров и посмотрите, как он работает.

Все операции соединения являются обходными решениями SQL. Они странный SQL-изм и не имеют никакого отношения к базовым объектам. Поэтому прекратите использовать терминологию SQL для описания того, что вы хотите.

1 голос
/ 02 декабря 2009

Забудьте SQL. Чего вы хотите добиться с помощью этого запроса? Что вы хотите сделать с результатами?

Вы не опубликовали свои модели. У них определены внешние ключи? Вы можете просто выполнить простой запрос и использовать select_related(), чтобы получить объединенные объекты?

Отредактировано для добавления Что не так с ответом, данным в прошлый раз, когда вы задавали этот вопрос ?

Отредактировано снова но все показали вам, как получить предмет через внешний ключ! Забудьте идентификатор, он вам не нужен. Если у вас есть Account объект a, вы просто делаете a.default_address, чтобы получить фактический Address связанный объект. Если это не сработает, значит, вы не публикуете правильные модели, так как это определенно будет работать с опубликованными вами моделями.

1 голос
/ 02 декабря 2009

Django предоставляет чистый способ возврата к нативному SQL для сложных запросов, см. Официальную документацию: Выполнение необработанных запросов SQL

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...