풀스택 개발 공부로그

Django Migrations

|

Django Migrate

Django model의 변경내역을 데이터베이스의 스키마에 반영하는 기능

migrate 정방향, 역방향

정방향

python manage.py migrate <앱이름>

미적용 파일 부터 최근 마이그레이션까지 정방향으로 순차적으로 수행

역방향

python manage.py migrate <앱이름> <마이그레이션 이름>

지정된 마이그레이션이 현재 적용된 마이그레이션보다 이후라면 정방향으로 지정 마이그레이션까지 forward수행

이전이라면, 역방향으로 순차적으로 지정마이그레이션 이전까지 backward수행

1, 2, 3, 4 마이그레이션이 있고, 4번까지 마이그레이션이 적용된 상태에서 migrate 0002를 하면 4, 3 순서되로 마이그레이션이 취소된다. 최종적으로 2번 마이그레이션이 적용된 상태로 가게된다.

Foreignkey Constraint

|

foreign key constraint

SQL FOREIGN KEY Constraint

A FOREIGN KEY is a key used to link two tables together. A FOREIGN KEY is a field (or collection of fields) in one table that refers to the PRIMARY KEY in another table.

FK는 두 테이블을 연결한다. FK는 다른 테이블의 PK를 참조한다.

The table containing the foreign key is called the child table, and the table containing the candidate key is called the referenced or parent table.

FK가 있는 테이블은 child table, candidate key를 가지고 있는 테이블은 parent table이라고 한다.

The FOREIGN KEY constraint also prevents invalid data from being inserted into the foreign key column, because it has to be one of the values contained in the table it points to.

foreign key constraint는 유효하지 않은 데이터가 foreign key column에 삽입되는것을 방지합니다. 삽입하려는 값이 FK가 가리키고 있는 테이블에 있는 값들 중 하나여야 하기 때문입니다.

Django Restframework Serializers Overview

|

Introduction

참조 : Django Rest Framework Serialization

Serializer class

The first thing we need to get started on our Web API is to provide a way of serializing and deserializing the snippet instances into representations such as json.

Web API를 시작할 때 알아야 할 부분은 모델 인스턴스를 json과 같은 형식으로 표현할 줄 알아야 합니다. 이를 직렬화 비직렬화 라고 합니다.

from rest_framework import serializers
from snippets.models import Snippet, LANGUAGE_CHOICES, STYLE_CHOICES


class SnippetSerializer(serializers.Serializer):
    id = serializers.IntegerField(read_only=True)
    title = serializers.CharField(required=False, allow_blank=True, max_length=100)
    code = serializers.CharField(style={'base_template': 'textarea.html'})
    linenos = serializers.BooleanField(required=False)
    language = serializers.ChoiceField(choices=LANGUAGE_CHOICES, default='python')
    style = serializers.ChoiceField(choices=STYLE_CHOICES, default='friendly')

    def create(self, validated_data):
        """
        Create and return a new `Snippet` instance, given the validated data.
        """
        return Snippet.objects.create(**validated_data)

    def update(self, instance, validated_data):
        """
        Update and return an existing `Snippet` instance, given the validated data.
        """
        instance.title = validated_data.get('title', instance.title)
        instance.code = validated_data.get('code', instance.code)
        instance.linenos = validated_data.get('linenos', instance.linenos)
        instance.language = validated_data.get('language', instance.language)
        instance.style = validated_data.get('style', instance.style)
        instance.save()
        return instance

Dealing with multiple objects

Dealing with multiple objects

The Serializer class can also handle serializing or deserializing lists of objects. To serialize a queryset or list of objects instead of a single object instance, you should pass the many=True flag when instantiating the serializer. You can then pass a queryset or list of objects to be serialized.

object를 serialize, deserialize하는것 이외에도 쿼리셋도 같은 작업을 할 수 있다. many=True 옵션을 주면된다.

queryset = Book.objects.all()
serializer = BookSerializer(queryset, many=True)
serializer.data
# [
#     {'id': 0, 'title': 'The electric kool-aid acid test', 'author': 'Tom Wolfe'},
#     {'id': 1, 'title': 'If this is a man', 'author': 'Primo Levi'},
#     {'id': 2, 'title': 'The wind-up bird chronicle', 'author': 'Haruki Murakami'}
# ]

ModelSerializers

ModelSerializer

  • An automatically determined set of fields.
  • Simple default implementations for the create() and update() methods.
class SnippetSerializer(serializers.ModelSerializer):
    class Meta:
        model = Snippet
        fields = [id, title, code, linenos, language, style]

ModelSerializer는 serializer에서 직접 작성해줘야하는 save, update같은 함수를 자동으로 만들어준다. 또한 메타클레스에 필드명만 입력해줘도 자동으로 serializer에서 정의하는 필드들을 완성해준다.

Often you’ll want serializer classes that map closely to Django model definitions. The ModelSerializer class provides a shortcut that lets you automatically create a Serializer class with fields that correspond to the Model fields. TheModelSerializerclass is the same as a regularSerializerclass, except that:

  • It will automatically generate a set of fields for you, based on the model.
  • It will automatically generate validators for the serializer, such as unique_together validators.
  • It includes simple default implementations of .create() and .update(). Declaring a ModelSerializer looks like this:

모델시리얼라이저는 Serializer와 동일한 기능을하고 추가적으로 편리한 기능을 제공한다. 모델만 입력해주면 자동으로 모든 필드에 대해 처리를 해준다. 하지만 웬만하면 사용하지 않을것이다. 성능의 저하를 가져온다.

Writing regular Django views using our Serializer

@csrf_exempt
def snippet_list(request):
    """
    List all code snippets, or create a new snippet.
    """
    if request.method == 'GET':
        snippets = Snippet.objects.all()
        serializer = SnippetSerializer(snippets, many=True)
        return JsonResponse(serializer.data, safe=False)

    elif request.method == 'POST':
        data = JSONParser().parse(request)
        serializer = SnippetSerializer(data=data)
        if serializer.is_valid():
            serializer.save()
            return JsonResponse(serializer.data, status=201)
        return JsonResponse(serializer.errors, status=400)

Django Restframework Serializer Performance Compare

|

DJango documentation

Performance and optimization | Django documentation | Django

Serialization Performance

Improve Serialization Performance in Django Rest Framework | Haki Benita

summary :

  • UserModelSerializer : 12.818s
  • UserReadOnlyModelSerializer : 7.407s
  • UserSerializer : 2.101s
  • UserReadOnlySerializer : 2.254s
  • serialize_user : 0.034s
  1. serializer is faster than modelserializer.
  2. marking the fields as readonly didn’t make a significant difference compared to the “regular” serializer.

시리얼라이저는 모델 시리얼 라이저보다 빠르고, Readonly는 성능에 큰 영향을 주지 않는다.

Optimization

Basic Performance Optimization in Django


19 Oct 2019 4:35 PM

Django Model Overview

|

Django Model

참고 : Django Model Documentation

Overview

A model is the single, definitive source of information about your data. It contains the essential fields and behaviors of the data you’re storing. Generally, each model maps to a single database table.

모델은 데이터에 대한 정보 소스 입니다. 필드와 데이터의 동작이 포함되어 있습니다. 일반적으로 각 모델은 하나의 데이터베이스 테이블에 매칭됩니다.

  • Each model is a Python class that subclasses django.db.models.Model .
  • Each attribute of the model represents a database field.
  • With all of this, Django gives you an automatically-generated database-access API; see Making queries .
from django.db import models

class Person(models.Model):
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=30)
  • The name of the table, myapp_person, is automatically derived from some model metadata but can be overridden. See Table names for more details.
  • An id field is added automatically, but this behavior can be overridden. See Automatic primary key fields .
  • The CREATE TABLE SQL in this example is formatted using PostgreSQL syntax, but it’s worth noting Django uses SQL tailored to the database backend specified in your settings file .

앱 이름이 myapp, 모델 이름이 person이라면 데이터 베이스에 저장되는 테이블에 이름은 mysqpp_person이 됩니다. id 필드는 자동으로 추가되며 오버라이드 할 수 있습니다.

Relationships

Many-to-one relationships

To define a many-to-one relationship, use django.db.models.ForeignKey . You use it just like any other Field type: by including it as a class attribute of your model. ForeignKey requires a positional argument: the class to which the model is related.

from django.db import models

class Manufacturer(models.Model):
    # ...
    pass

class Car(models.Model):
    manufacturer = models.ForeignKey(Manufacturer, on_delete=models.CASCADE)
    # ...

ForeignKey fields accept a number of extra arguments which are explained in the model field reference . These options help define how the relationship should work; all are optional.

Many-to-many relationships

For example, if a Pizza has multiple Topping objects – that is, a Topping can be on multiple pizzas and each Pizza has multiple toppings – here’s how you’d represent that:

from django.db import models

class Topping(models.Model):
    # ...
    pass

class Pizza(models.Model):
    # ...
    toppings = models.ManyToManyField(Topping)

One-to-one relationships

This is most useful on the primary key of an object when that object “extends” another object in some way. For example, if you were building a database of “places”, you would build pretty standard stuff such as address, phone number, etc. in the database. Then, if you wanted to build a database of restaurants on top of the places, instead of repeating yourself and replicating those fields in the Restaurant model, you could make Restaurant have a OneToOneField to Place (because a restaurant “is a” place; in fact, to handle this you’d typically use inheritance , which involves an implicit one-to-one relation). As with ForeignKey , a recursive relationship can be defined and references to as-yet undefined models can be made.

from django.db import models

class Place(models.Model):
    name = models.CharField(max_length=50)
    address = models.CharField(max_length=80)

    def __str__(self):
        return "%s the place" % self.name

class Restaurant(models.Model):
    place = models.OneToOneField(
        Place,
        on_delete=models.CASCADE,
        primary_key=True,
    )
    serves_hot_dogs = models.BooleanField(default=False)
    serves_pizza = models.BooleanField(default=False)

    def __str__(self):
        return "%s the restaurant" % self.place.name

place라는 데이터 베이스를 만들 때 주소나 전화번호 같은것으로 특정지을 수 있지만, Restaurant과 같은 모델을 하나 더 만들어 place를 표현할 수 있다.

Meta options

Give your model metadata by using an inner class Meta, like so:

from django.db import models

class Ox(models.Model):
    horn_length = models.IntegerField()

    class Meta:
        ordering = ["horn_length"]
        verbose_name_plural = "oxen"

Model metadata is “anything that’s not a field”, such as ordering options ( ordering ), database table name ( db_table ), or human-readable singular and plural names ( verbose_name and verbose_name_plural ). None are required, and adding class Meta to a model is completely optional. A complete list of all possible Meta options can be found in the model option reference .

메타데이터 모델은 “필드가 아닌 모든”것입니다. 정렬 순서라든가, 데이터베이스 테이블 이름, 사람이 읽기 편한 이름 등등.

Model methods

참고 : Models | Django documentation | Django

objects The most important attribute of a model is the Manager . It’s the interface through which database query operations are provided to Django models and is used to retrieve the instances from the database. If no custom Manager is defined, the default name is objects . Managers are only accessible via model classes, not the model instances.

Model inheritance

Abstract base classes

Abstract base classes are useful when you want to put some common information into a number of other models. You write your base class and put abstract=True in the Meta class. This model will then not be used to create any database table. Instead, when it is used as a base class for other models, its fields will be added to those of the child class. An example:

from django.db import models

class CommonInfo(models.Model):
    name = models.CharField(max_length=100)
    age = models.PositiveIntegerField()

    class Meta:
        abstract = True		
        ordering = ['name']

class Student(CommonInfo):
    home_group = models.CharField(max_length=5)

The Student model will have three fields: name, age and home_group. The CommonInfo model cannot be used as a normal Django model, since it is an abstract base class.

Student 모델은 3개의 필드를 가지게 됩니다. name, age, home_group. CommonInfo 모델은 일반적인 장고 모델처럼 사용될 수 없습니다. 추상화 기반의 클래스 이기 때문입니다.


19 Oct 2019 12:08 AM