Использование django rest framework, как добавить новый вложенный дочерний объект для существующего родительского объекта. - PullRequest
0 голосов
/ 14 января 2019

Я пытаюсь создать хранилище данных для данных временных рядов, для этого я создал вложенные объекты Coin и Data, где Coin является родительским объектом и содержит записи данных, каждая запись которых является отдельным объектом. в этот момент мой код создает вложенный объект Coin [Data], когда я создаю функцию создания в CoinSerializer, но я не смог использовать правильный метод для добавления / создания дочернего объекта в существующем объекте Coin

В моей виртуальной среде python я использовал django 2.1.4 drf 3.9 и python 3.6 .. также в качестве внутреннего механизма БД для моего проекта, я получил mongodb и использую djongo 1.2 для его поддержки

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

models.py

class Coin(models.Model):
    coin_name = models.CharField(max_length=100,blank=True)


class Data(models.Model):
    coin = models.ForeignKey(Coin, related_name='data', on_delete=models.CASCADE,blank=True)
    date = models.DateField(("Date"),blank=True)
    open = models.FloatField(null=True, blank=True)
    high = models.FloatField(null=True, blank=True)
    low = models.FloatField(null=True, blank=True)
    close = models.FloatField(null=True, blank=True)

    class Meta:
        unique_together = ('coin', 'date',)
        ordering = ['date']

    def __unicode__(self):
        return '%d: %d %d %d %d' % (self.date, self.open, self.high, 
self.low, self.close)

serializers.py

class DataSerializer(serializers.ModelSerializer):
class Meta():
    model = models.Data
    fields = ('coin_id','pk','id','date','open','high','low','close')

Класс CoinSerializer (serializers.ModelSerializer): data = DataSerializer (много = True)

class Meta:
    model = models.Coin
    fields = ('pk','id','coin_name', 'data')

def create(self, validated_data):

    data = validated_data.pop('data')
    coin = models.Coin.objects.create(**validated_data)
    models.Data.objects.create(coin=coin, **data[0])

    return coin

мой результат такой

 {
    "pk": 101,
    "id": 101,
    "coin_name": "ripple",
    "data": [
        {
            "coin_id": 101,
            "pk": 56,
            "id": 56,
            "date": "2016-12-25",
            "open": 4036.0,
            "high": 4101.0,
            "low": 3983.0,
            "close": 4065.0
        }
    ]
     },

and expect to consist lots of data objects which I will add by the time in existing coin object

 {
    "pk": 101,
    "id": 101,
    "coin_name": "ripple",
    "data": [
        {
            "coin_id": 101,
            "pk": 56,
            "id": 56,
            "date": "2016-12-25",
            "open": 4036.0,
            "high": 4101.0,
            "low": 3983.0,
            "close": 4065.0
        }
        {
            "coin_id": 102,
            "pk": 57,
            "id": 57,
            "date": "2016-12-26",
            "open": 4065.0,
            "high": 4189.0,
            "low": 3967.0,
            "close": 4075.0
        }
        ...
        ...
    ]
     },

Ответы [ 2 ]

0 голосов
/ 14 января 2019

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

data = [{'date': '2016-12-25', 'high': 4101.0, 'open': 0.0, 'low': 3983.0, 'close': 4065.0}, {'date': '2016-12-26', 'high': 4101.0, 'open': 0.0, 'low': 3983.0, 'close': 4065.0}]

В этом примере есть еще один элемент в массиве data. И измени эту строку:

coin = models.Coin.objects.create(**validated_data)
models.Data.objects.create(coin=coin, **data[0])

до

coin = models.Coin.objects.create(**validated_data)
for item_data in data:
    models.Data.objects.create(coin=coin, **item_data)

Это создаст Data с FK Coin.

0 голосов
/ 14 января 2019

Вы идете об этом неправильно. Вместо этого вам следует создать другую конечную точку для данных. Там вы можете создать данные и передать идентификатор родительской монеты. Использование вложенной архитектуры имеет смысл только тогда, когда вы одновременно создаете монету и данные. В этом случае просто используйте конечную точку данных для создания данных при передаче идентификатора монеты

РЕДАКТИРОВАТЬ: ОБЪЕМНОЕ СОЗДАНИЕ

И просто для того, чтобы немного осветить, как реализовать массовое создание для нескольких объектов данных - вам нужно будет реализовать его с помощью цикла, так как model.objects.create() ожидает данные для одного объекта. Вы можете использовать bulk_create , но у него много предостережений, поэтому я бы использовал цикл

...