Как создать несколько таблиц из одного вызова API, используя django? - PullRequest
2 голосов
/ 12 февраля 2020

Я разработчик FE, который пытается проникнуть в мир Python & Django.

Чтобы узнать это, я создаю своего рода приложение для трейдинга. У меня есть 2 модели. User и UserPortfolio. В настоящее время я могу создавать обе таблицы независимо через 2 разных вызова API. Однако я хотел бы иметь возможность создавать UserPortfolio при создании User. Я установил OneToOne связь между таблицами.

Используя python, как лучше всего добиться этого эффективно? Очень быстрый вопрос, является ли хорошей практикой в ​​Django разделение моделей внутри проекта на их собственные файлы?

Заранее спасибо за вашу помощь! :)

Внутри папки с названием models мой user.py выглядит следующим образом:

from django.db import models
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager, \
                                       PermissionsMixin

from .user_portfolio import UserPortfolio                                       

class UserManager(BaseUserManager):

    def create_user(self, email, password=None, **extra_fields):
        """Creates and saves new user"""

        if not email:
            raise ValueError('Email address is required')

        user = self.model(email=self.normalize_email(email), **extra_fields)
        user.set_password(password)
        user.save(using=self._db)

        return user

class User(AbstractBaseUser, PermissionsMixin):
    """Custom user model that supports using email instead of username"""

    email = models.EmailField(max_length=255, unique=True)
    first_name = models.CharField(max_length=255)
    last_name = models.CharField(max_length=255)
    date_of_birth = models.CharField(max_length=255)
    phone_number = models.IntegerField(null=True)
    is_active = models.BooleanField(default=True)
    last_login = models.DateTimeField(auto_now_add=True)
    created_on = models.DateTimeField(auto_now_add=True)

    objects = UserManager()

    USERNAME_FIELD = 'email'

в другом файле user_portfolio.py, у меня есть модель, и она выглядит так:

from django.db import models
from django.conf import settings

class UserPortfolioManager(models.Manager):
    """User Portfolio Manager"""
    def create_user_portfolio(self, user_id, **extra_fields):

        user_portfolio = self.model(user_id=user_id, **extra_fields)
        user_portfolio.save(using=self._db)

        return user_portfolio


class UserPortfolio(models.Model):
    """User portfolio model"""

    amount_invested = models.FloatField()
    profits = models.IntegerField(default=0)
    loss = models.IntegerField(default=0)
    user = models.OneToOneField(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE
    )

    objects = UserPortfolioManager()

    def __str__(self):
        return 'Created!'

У меня есть файл для моих сериализаторов:

from django.contrib.auth import get_user_model

from rest_framework import serializers

from core.models import UserPortfolio

class UserPortfolioSerializer(serializers.ModelSerializer):
    """Serialzier from user portfolio object"""

    class Meta:
        model = UserPortfolio
        fields =(
            'id', 
            'amount_invested',
            'profits',
            'loss',
        )
        read_only_fields = ('id',)

    def create(self, validated_data):
        print(validated_data)
        return UserPortfolio.objects.create_user_portfolio(user_id=user_id, **validated_data)

class UserSerializer(serializers.ModelSerializer):
    """Serializer for users object"""
    class Meta:
        model = get_user_model()
        fields = (
            'email',
            'password',
            'first_name',
            'last_name',
            'date_of_birth',
            'phone_number'
        )
        extra_kwargs = {'password': {'write_only': True, 'min_length': 5}}

    def create(self, validated_data):
        """Create a new user with encrypted password and return it"""
        return get_user_model().objects.create_user(**validated_data)


и мой views.py файл:

from rest_framework import generics, viewsets, mixins, serializers
from rest_framework.authentication import TokenAuthentication
from rest_framework.permissions import IsAuthenticated

from core.models import UserPortfolio

from user.serializers import UserSerializer, UserPortfolioSerializer


class CreateUserView(generics.CreateAPIView):
    """Create new user in the system"""
    serializer_class = UserSerializer


class CreateUserPortfolioView(generics.CreateAPIView):
    serializer_class = UserPortfolioSerializer

В настоящее время я понимаю, что * Таблица 1029 * будет иметь user_id, которая ссылается на пользователя, которому принадлежит портфель. Портфель должен быть уникальным для пользователя и может принадлежать только одному пользователю, и тогда у пользователя может быть только один портфель.

1 Ответ

1 голос
/ 12 февраля 2020

Вы можете сделать это, изменив логи c в одном из ваших сериализаторов. Я изменит ваш UserPortfolioSerializer на что-то вроде ниже.

class UserPortfolioSerializer(serializers.ModelSerializer):
    class Meta:
        model = UserPortfolio
        fields =(
            'id',
            'user', 
            'amount_invested',
            'profits',
            'loss',
        )
        read_only_fields = ('id',)

    def create(self, validated_data):
        user_data = validated_data.pop(user)
        user = User.objects.create_user(**user_data)
        return UserPortfolio.objects.create_user_portfolio(user=user, **validated_data)

Теперь вам нужно изменить формат ввода, как показано ниже:

{
    "user": {
            ....
            # user information here
            ....
            }
    ....
    # user portfolio information here
    ....
}

Это основная идея, чтобы решить вашу проблему , Я думаю, что вы поняли :). Этим вы можете делать любые изменения в логи c внутри вашего сериализатора.

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