Как бы я повторил этот запрос SQL в Django Rest Framework, используя generics.ListAPIView и serializers.ModelSerializer - PullRequest
0 голосов
/ 07 ноября 2019

Не могу найти что-то похожее на то, что я пытаюсь сделать с желанием использовать операторы case и левые объединения с использованием DRF Django Rest Framework, да, это можно сделать на внешнем интерфейсе проекта, над которым я работаю, но id, скорее всего, нетпозволить внешнему интерфейсу потенциально отправлять сотни запросов при загрузке списка продуктов, например.

Ничего, что я действительно могу добавить к этому, но я пробовал много разных способов сделать ниже

SELECT 
    p.itemno,
    CASE
        WHEN cp.price IS NULL THEN p.HighSell
        ELSE cp.price
    END AS price
FROM
    api_product AS p
        LEFT JOIN
    api_customerprices AS cp ON p.itemno = cp.itemno
            AND cp.customerno = 'Examplecust'
WHERE
    p.FreeStock > 0
        or restockDate > '1900-01-01'

Вот мои модели:

class Product(models.Model):
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    itemno = models.CharField(max_length=100)
    description = models.TextField(null=True)
    colour = models.CharField(max_length=100, null=True)
    manufacturerCode = models.CharField(max_length = 100, null=True)
    RRP = models.DecimalField(max_digits=6, decimal_places=2, null=True)
    SSP = models.DecimalField(max_digits=6, decimal_places=2,null=True)
    FreeStock = models.IntegerField(null=True)
    ItemSpec1 = models.CharField(max_length=100, null=True)
    ItemSpec2 = models.CharField(max_length=100, null=True)
    ItemSpec3 = models.CharField(max_length=100, null=True)
    ItemSpec4 = models.CharField(max_length=100, null=True)
    ItemSpec5 = models.CharField(max_length=100, null=True)
    ItemSpec6 = models.CharField(max_length=100, null=True)
    ItemSpec7 = models.CharField(max_length=100, null=True)
    ItemSpec8 = models.CharField(max_length=100, null=True)
    ItemSpec9 = models.CharField(max_length=100, null=True)
    ItemSpec10 = models.CharField(max_length=100, null=True)
    TI = models.IntegerField(null=True)
    HI = models.IntegerField(null=True)
    Item_Height = models.DecimalField(max_digits=6, decimal_places=2, null=True)
    Item_Length = models.DecimalField(max_digits=6, decimal_places=2, null=True)
    Item_Width = models.DecimalField(max_digits=6, decimal_places=2, null=True)
    ProductPaging_Height = models.DecimalField(max_digits=6, decimal_places=2, null=True)
    ProductPaging_Length = models.DecimalField(max_digits=6, decimal_places=2, null=True)
    ProductPaging_Width = models.DecimalField(max_digits=6, decimal_places=2, null=True)
    CartonHeight = models.DecimalField(max_digits=6, decimal_places=2, null=True)
    CartonLength = models.DecimalField(max_digits=6, decimal_places=2, null=True)
    CartonWidth = models.DecimalField(max_digits=6, decimal_places=2, null=True)
    palletQty = models.IntegerField(null=True)
    cartonQty = models.IntegerField(null=True)
    restockDate = models.DateField(null=True)
    IPG = models.CharField(max_length=100, null=True)
    CatalogueTheme = models.CharField(max_length=100, null=True)
    Analysis2 = models.CharField(max_length=100, null=True)
    Electrical_or_Housewares = models.CharField(max_length=100, null=True)
    HighSell = models.DecimalField(max_digits=6, decimal_places=2, null=True)
    Analysis1 = models.CharField(max_length=100, null=True)
    Image = models.TextField(null=True, blank=True)
    MarketingText = models.TextField(null=True, blank=True)
    SearchTerms = models.TextField(null=True, blank=True)
    ItemVariant = models.CharField(max_length=100)
    Categories = models.CharField(max_length=249, null=True)

    def __str__(self):
        return self.itemno

class CustomerPrices(models.Model):
    customerNo = models.CharField(max_length=20)
    itemno = models.CharField(max_length=20)
    price = models.DecimalField(max_digits=6, decimal_places=2)
    startDate = models.DateField()
    endDate = models.DateField()

    def __str__(self):
        return self.customerNo

Вот мои сериализаторы

class OauthProdListSerializer(serializers.ModelSerializer):
    class Meta:
        model = Product
        fields = (
            'id',
            'itemno',
            'description',
            'colour',
            'RRP',
            'SSP',
            'manufacturerCode',
            'FreeStock',
            'restockDate',
            'Image',
            'HighSell',
            'ItemVariant',
            'Categories'
        )

class OCustomerPricesSerializer(serializers.ModelSerializer):
    class Meta:
        model = CustomerPrices
        fields = (
            'id',
            'customerNo',
            'itemno',
            'price'
        )

Ответы [ 3 ]

0 голосов
/ 07 ноября 2019

Я не совсем уверен, что вы имеете в виду, но вы можете получить SQL для всех таблиц в приложении, выполнив следующую команду: python manage.py sqlall your_app

или вы хотите преобразовать sql в djangoиспользуйте: Person.objects.raw ('your_sql_querry')

0 голосов
/ 11 ноября 2019

Нашел способ выполнить то, что хотел, оказалось, что мне не хватало знаний о методе SerializerMethodField (), как только я узнал, что получил его довольно быстро.

class ProdListSerializer(ModelSerializer):
price = SerializerMethodField()
class Meta:
    model = Product
    fields = [
        'id',
        'itemno',
        'description',
        'colour',
        'RRP',
        'SSP',
        'manufacturerCode',
        'FreeStock',
        'restockDate',
        'Image',
        'ItemVariant',
        'Categories',
        'price'
    ]

def get_price(self, obj):
    itemno = obj.itemno
    customerNo = self._context['view'].request.query_params.get('customerNo', '')
    if customerNo:
        customerPrice = CustomerPrices.objects.filter(
            Q(customerNo=customerNo) &
            Q(itemno=itemno)
        ).values('price').first()
        if customerPrice:
            return customerPrice
        else:
            return Product.objects.filter(itemno=itemno).values('HighSell').first()
    else:
        return Product.objects.filter(itemno=itemno).values('HighSell').first()
0 голосов
/ 07 ноября 2019

Я просто пишу это с головы до головы, поэтому с вашей стороны потребуется некоторое усилие, чтобы все заработало.

У вас нет отношений между вашим продуктом и ценами клиента. Вам нужно будет либо добавить Foreignkey между двумя таблицами напрямую, либо добавить промежуточную таблицу с Foreignkeys между ними. Ваш запрос будет выглядеть примерно так:

Q - это объект запроса django - см. Сложные поиски с объектами Q

results = CustomerPrices.objects.filter(
    Q(itemno__FreeStock__gt=0) | Q(itemno__restockDate__gt='1900-0-01'),
    customerno='Examplecust'
)

# Your case statement can be handled in your code logic:

def case_statement(result):
    if not result.price:
        return result.HighSell
    return result.price
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...