<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>django-support.log</title>
        <link>https://velog.io/</link>
        <description></description>
        <lastBuildDate>Mon, 17 Oct 2022 09:30:26 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>django-support.log</title>
            <url>https://images.velog.io/images/django-support/profile/5954b891-2294-41e6-b36f-8bc22630ac33/dooh.jpeg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. django-support.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/django-support" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[django model fields 관계 조회
]]></title>
            <link>https://velog.io/@django-support/django-model-fields-%EA%B4%80%EA%B3%84-%EC%A1%B0%ED%9A%8C</link>
            <guid>https://velog.io/@django-support/django-model-fields-%EA%B4%80%EA%B3%84-%EC%A1%B0%ED%9A%8C</guid>
            <pubDate>Mon, 17 Oct 2022 09:30:26 GMT</pubDate>
            <description><![CDATA[<p><a href="http://daplus.net/django-django%EC%97%90%EC%84%9C-%EB%AA%A8%EB%8D%B8-%ED%95%84%EB%93%9C-%EA%B0%80%EC%A0%B8-%EC%98%A4%EA%B8%B0/">http://daplus.net/django-django%EC%97%90%EC%84%9C-%EB%AA%A8%EB%8D%B8-%ED%95%84%EB%93%9C-%EA%B0%80%EC%A0%B8-%EC%98%A4%EA%B8%B0/</a></p>
<pre><code class="language-python">def get_model_fields(model):
    return model._meta.fields</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[docker build error]]></title>
            <link>https://velog.io/@django-support/docker-build-error</link>
            <guid>https://velog.io/@django-support/docker-build-error</guid>
            <pubDate>Fri, 07 Oct 2022 20:21:48 GMT</pubDate>
            <description><![CDATA[<h4 id="mysql_-부분에서-라이브러리가-필요-했던거-같다-해서">mysql_ 부분에서 라이브러리가 필요 했던거 같다 해서</h4>
<pre><code>&gt; [stage-0 5/8] RUN         --mount=type=cache,target=/root/.cache/pip             pip install -r /tmp/requirements.txt:
#13 0.925 Ignoring appnope: markers &#39;platform_system == &quot;Darwin&quot; and python_version &gt;= &quot;3.8&quot; and sys_platform == &quot;darwin&quot;&#39; don&#39;t match your environment
#13 0.926 Ignoring cffi: markers &#39;implementation_name == &quot;pypy&quot; and python_version &gt;= &quot;3.7&quot;&#39; don&#39;t match your environment
#13 0.926 Ignoring colorama: markers &#39;python_version &gt;= &quot;3.8&quot; and python_full_version &lt; &quot;3.0.0&quot; and sys_platform == &quot;win32&quot; or sys_platform == &quot;win32&quot; and python_version &gt;= &quot;3.8&quot; and python_full_version &gt;= &quot;3.5.0&quot;&#39; don&#39;t match your environment
#13 0.927 Ignoring py: markers &#39;python_version &gt;= &quot;3.7&quot; and python_full_version &lt; &quot;3.0.0&quot; and implementation_name == &quot;pypy&quot; or implementation_name == &quot;pypy&quot; and python_version &gt;= &quot;3.7&quot; and python_full_version &gt;= &quot;3.5.0&quot;&#39; don&#39;t match your environment
#13 0.928 Ignoring pycparser: markers &#39;python_version &gt;= &quot;3.7&quot; and python_full_version &lt; &quot;3.0.0&quot; and implementation_name == &quot;pypy&quot; or implementation_name == &quot;pypy&quot; and python_version &gt;= &quot;3.7&quot; and python_full_version &gt;= &quot;3.4.0&quot;&#39; don&#39;t match your environment
#13 0.928 Ignoring pywin32: markers &#39;sys_platform == &quot;win32&quot; and platform_python_implementation != &quot;PyPy&quot; and python_version &gt;= &quot;3.7&quot;&#39; don&#39;t match your environment
#13 0.928 Ignoring pywinpty: markers &#39;os_name == &quot;nt&quot; and python_version &gt;= &quot;3.7&quot;&#39; don&#39;t match your environment
#13 0.928 Ignoring tzdata: markers &#39;sys_platform == &quot;win32&quot; and python_version &gt;= &quot;3.8&quot;&#39; don&#39;t match your environment
#13 0.999 Collecting argon2-cffi-bindings==21.2.0
#13 1.000   Using cached argon2_cffi_bindings-21.2.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (80 kB)
#13 1.031 Collecting argon2-cffi==21.3.0
#13 1.032   Using cached argon2_cffi-21.3.0-py3-none-any.whl (14 kB)
#13 1.062 Collecting asgiref==3.5.2
#13 1.062   Using cached asgiref-3.5.2-py3-none-any.whl (22 kB)
#13 1.093 Collecting asttokens==2.0.5
#13 1.094   Using cached asttokens-2.0.5-py2.py3-none-any.whl (20 kB)
#13 1.114 Collecting attrs==21.4.0
#13 1.115   Using cached attrs-21.4.0-py2.py3-none-any.whl (60 kB)
#13 1.132 Collecting backcall==0.2.0
#13 1.133   Using cached backcall-0.2.0-py2.py3-none-any.whl (11 kB)
#13 1.162 Collecting beautifulsoup4==4.11.1
#13 1.163   Using cached beautifulsoup4-4.11.1-py3-none-any.whl (128 kB)
#13 1.187 Collecting bleach==5.0.1
#13 1.188   Using cached bleach-5.0.1-py3-none-any.whl (160 kB)
#13 1.255 Collecting debugpy==1.6.2
#13 1.274   Using cached debugpy-1.6.2-py2.py3-none-any.whl (4.4 MB)
#13 1.305 Collecting decorator==5.1.1
#13 1.306   Using cached decorator-5.1.1-py3-none-any.whl (9.1 kB)
#13 1.324 Collecting defusedxml==0.7.1
#13 1.325   Using cached defusedxml-0.7.1-py2.py3-none-any.whl (25 kB)
#13 1.361 Collecting django-extensions==3.2.0
#13 1.362   Using cached django_extensions-3.2.0-py3-none-any.whl (229 kB)
#13 1.383 Collecting django-hashid-field==3.3.5
#13 1.383   Using cached django_hashid_field-3.3.5-py3-none-any.whl (19 kB)
#13 1.405 Collecting django-phonenumber-field==6.3.0
#13 1.406   Using cached django_phonenumber_field-6.3.0-py3-none-any.whl (65 kB)
#13 1.426 Collecting django-rest-framework==0.1.0
#13 1.427   Using cached django-rest-framework-0.1.0.tar.gz (969 bytes)
#13 1.429   Preparing metadata (setup.py): started
#13 1.639   Preparing metadata (setup.py): finished with status &#39;done&#39;
#13 1.692 Collecting django==4.0.6
#13 1.717   Using cached Django-4.0.6-py3-none-any.whl (8.0 MB)
#13 1.773 Collecting djangorestframework==3.13.1
#13 1.775   Using cached djangorestframework-3.13.1-py3-none-any.whl (958 kB)
#13 1.796 Collecting entrypoints==0.4
#13 1.797   Using cached entrypoints-0.4-py3-none-any.whl (5.3 kB)
#13 1.814 Collecting et-xmlfile==1.1.0
#13 1.815   Using cached et_xmlfile-1.1.0-py3-none-any.whl (4.7 kB)
#13 1.841 Collecting executing==0.9.1
#13 1.842   Using cached executing-0.9.1-py2.py3-none-any.whl (16 kB)
#13 1.867 Collecting fastjsonschema==2.16.1
#13 1.868   Using cached fastjsonschema-2.16.1-py3-none-any.whl (22 kB)
#13 1.890 Collecting gunicorn==20.1.0
#13 1.890   Using cached gunicorn-20.1.0-py3-none-any.whl (79 kB)
#13 1.909 Collecting hashids==1.3.1
#13 1.910   Using cached hashids-1.3.1-py2.py3-none-any.whl (6.6 kB)
#13 1.941 Collecting ipykernel==6.15.1
#13 1.942   Using cached ipykernel-6.15.1-py3-none-any.whl (132 kB)
#13 1.963 Collecting ipython-genutils==0.2.0
#13 1.964   Using cached ipython_genutils-0.2.0-py2.py3-none-any.whl (26 kB)
#13 2.001 Collecting ipython==8.4.0
#13 2.003   Using cached ipython-8.4.0-py3-none-any.whl (750 kB)
#13 2.029 Collecting jedi==0.18.1
#13 2.032   Using cached jedi-0.18.1-py2.py3-none-any.whl (1.6 MB)
#13 2.074 Collecting jinja2==3.1.2
#13 2.075   Using cached Jinja2-3.1.2-py3-none-any.whl (133 kB)
#13 2.101 Collecting jsonschema==4.7.2
#13 2.102   Using cached jsonschema-4.7.2-py3-none-any.whl (81 kB)
#13 2.128 Collecting jupyter-client==7.3.4
#13 2.129   Using cached jupyter_client-7.3.4-py3-none-any.whl (132 kB)
#13 2.152 Collecting jupyter-core==4.11.1
#13 2.153   Using cached jupyter_core-4.11.1-py3-none-any.whl (88 kB)
#13 2.182 Collecting jupyterlab-pygments==0.2.2
#13 2.183   Using cached jupyterlab_pygments-0.2.2-py2.py3-none-any.whl (21 kB)
#13 2.219 Collecting markupsafe==2.1.1
#13 2.220   Using cached MarkupSafe-2.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (26 kB)
#13 2.240 Collecting matplotlib-inline==0.1.3
#13 2.241   Using cached matplotlib_inline-0.1.3-py3-none-any.whl (8.2 kB)
#13 2.263 Collecting mistune==0.8.4
#13 2.264   Using cached mistune-0.8.4-py2.py3-none-any.whl (16 kB)
#13 2.308 Collecting mysql-connector-python==8.0.30
#13 2.310   Using cached mysql_connector_python-8.0.30-py2.py3-none-any.whl (351 kB)
#13 2.334 Collecting mysqlclient==2.1.1
#13 2.335   Using cached mysqlclient-2.1.1.tar.gz (88 kB)
#13 2.344   Preparing metadata (setup.py): started
#13 2.432   Preparing metadata (setup.py): finished with status &#39;error&#39;
#13 2.435   error: subprocess-exited-with-error
#13 2.435
#13 2.435   × python setup.py egg_info did not run successfully.
#13 2.435   │ exit code: 1
#13 2.435   ╰─&gt; [16 lines of output]
#13 2.435       /bin/sh: 1: mysql_config: not found
#13 2.435       /bin/sh: 1: mariadb_config: not found
#13 2.435       /bin/sh: 1: mysql_config: not found
#13 2.435       Traceback (most recent call last):
#13 2.435         File &quot;&lt;string&gt;&quot;, line 2, in &lt;module&gt;
#13 2.435         File &quot;&lt;pip-setuptools-caller&gt;&quot;, line 34, in &lt;module&gt;
#13 2.435         File &quot;/tmp/pip-install-mbdi6q9e/mysqlclient_3c45797ef9a34346a0cae3c665d8efca/setup.py&quot;, line 15, in &lt;module&gt;
#13 2.435           metadata, options = get_config()
#13 2.435         File &quot;/tmp/pip-install-mbdi6q9e/mysqlclient_3c45797ef9a34346a0cae3c665d8efca/setup_posix.py&quot;, line 70, in get_config
#13 2.435           libs = mysql_config(&quot;libs&quot;)
#13 2.435         File &quot;/tmp/pip-install-mbdi6q9e/mysqlclient_3c45797ef9a34346a0cae3c665d8efca/setup_posix.py&quot;, line 31, in mysql_config
#13 2.435           raise OSError(&quot;{} not found&quot;.format(_mysql_config_path))
#13 2.435       OSError: mysql_config not found
#13 2.435       mysql_config --version
#13 2.435       mariadb_config --version
#13 2.435       mysql_config --libs
#13 2.435       [end of output]
#13 2.435
#13 2.435   note: This error originates from a subprocess, and is likely not a problem with pip.
#13 2.436 error: metadata-generation-failed
#13 2.436
#13 2.436 × Encountered error while generating package metadata.
#13 2.436 ╰─&gt; See above for output.
#13 2.436
#13 2.436 note: This is an issue with the package mentioned above, not pip.
#13 2.436 hint: See above for details.
------
executor failed running [/bin/sh -c pip install -r /tmp/requirements.txt]: exit code: 1
(celly-pick-database-env) ☁  CellyPick [test] ⚡  docker build -t celly-pick-test .
[+] Building 5.7s (13/16)
 =&gt; [internal] load build definition from Dockerfile                                                                                                                                                                                              0.0s
 =&gt; =&gt; transferring dockerfile: 1.01kB                                                                                                                                                                                                            0.0s
 =&gt; [internal] load .dockerignore                                                                                                                                                                                                                 0.0s
 =&gt; =&gt; transferring context: 2B                                                                                                                                                                                                                   0.0s
 =&gt; resolve image config for docker.io/docker/dockerfile:experimental                                                                                                                                                                             1.3s
 =&gt; CACHED docker-image://docker.io/docker/dockerfile:experimental@sha256:600e5c62eedff338b3f7a0850beb7c05866e0ef27b2d2e8c02aa468e78496ff5                                                                                                        0.0s
 =&gt; [internal] load metadata for docker.io/library/python:3.10-slim                                                                                                                                                                               1.0s
 =&gt; [internal] load build context                                                                                                                                                                                                                 0.0s
 =&gt; =&gt; transferring context: 58.63kB                                                                                                                                                                                                              0.0s
 =&gt; [stage-0 1/9] FROM docker.io/library/python:3.10-slim@sha256:f2ee145f3bc4e061f8dfe7e6ebd427a410121495a0bd26e7622136db060c59e0                                                                                                                 0.0s
 =&gt; [internal] settings cache mount permissions                                                                                                                                                                                                   0.0s
 =&gt; CACHED [stage-0 2/9] RUN         ln -snf /usr/share/zoneinfo/Asia/Seoul /etc/localtime &amp;&amp; echo Asia/Seoul &gt; /etc/timezone                                                                                                                     0.0s
 =&gt; CACHED [stage-0 3/9] RUN         apt -y update &amp;&amp;            apt -y full-upgrade &amp;&amp;            apt -y install gettext &amp;&amp;             apt -y install libmagic1 &amp;&amp;             apt -y autoremove                                                0.0s
 =&gt; CACHED [stage-0 4/9] RUN         apt -y install gcc libpq-dev &amp;&amp;            pip install psycopg2-binary --no-binary psycopg2-binary &amp;&amp;            apt -y autoremove                                                                           0.0s
 =&gt; CACHED [stage-0 5/9] COPY        requirements.txt /tmp/requirements.txt                                                                                                                                                                       0.0s
 =&gt; ERROR [stage-0 6/9] RUN         --mount=type=cache,mode=0777,target=/root/.cache/pip pip install -r /tmp/requirements.txt                                                                                                                     3.2s
------
 &gt; [stage-0 6/9] RUN         --mount=type=cache,mode=0777,target=/root/.cache/pip pip install -r /tmp/requirements.txt:
#13 0.330 Ignoring appnope: markers &#39;platform_system == &quot;Darwin&quot; and python_version &gt;= &quot;3.8&quot; and sys_platform == &quot;darwin&quot;&#39; don&#39;t match your environment
#13 0.330 Ignoring cffi: markers &#39;implementation_name == &quot;pypy&quot; and python_version &gt;= &quot;3.7&quot;&#39; don&#39;t match your environment
#13 0.330 Ignoring colorama: markers &#39;python_version &gt;= &quot;3.8&quot; and python_full_version &lt; &quot;3.0.0&quot; and sys_platform == &quot;win32&quot; or sys_platform == &quot;win32&quot; and python_version &gt;= &quot;3.8&quot; and python_full_version &gt;= &quot;3.5.0&quot;&#39; don&#39;t match your environment
#13 0.332 Ignoring py: markers &#39;python_version &gt;= &quot;3.7&quot; and python_full_version &lt; &quot;3.0.0&quot; and implementation_name == &quot;pypy&quot; or implementation_name == &quot;pypy&quot; and python_version &gt;= &quot;3.7&quot; and python_full_version &gt;= &quot;3.5.0&quot;&#39; don&#39;t match your environment
#13 0.332 Ignoring pycparser: markers &#39;python_version &gt;= &quot;3.7&quot; and python_full_version &lt; &quot;3.0.0&quot; and implementation_name == &quot;pypy&quot; or implementation_name == &quot;pypy&quot; and python_version &gt;= &quot;3.7&quot; and python_full_version &gt;= &quot;3.4.0&quot;&#39; don&#39;t match your environment
#13 0.332 Ignoring pywin32: markers &#39;sys_platform == &quot;win32&quot; and platform_python_implementation != &quot;PyPy&quot; and python_version &gt;= &quot;3.7&quot;&#39; don&#39;t match your environment
#13 0.332 Ignoring pywinpty: markers &#39;os_name == &quot;nt&quot; and python_version &gt;= &quot;3.7&quot;&#39; don&#39;t match your environment
#13 0.333 Ignoring tzdata: markers &#39;sys_platform == &quot;win32&quot; and python_version &gt;= &quot;3.8&quot;&#39; don&#39;t match your environment
#13 0.392 Collecting argon2-cffi-bindings==21.2.0
#13 0.476   Downloading argon2_cffi_bindings-21.2.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (80 kB)
#13 0.496      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 80.6/80.6 kB 4.0 MB/s eta 0:00:00
#13 0.533 Collecting argon2-cffi==21.3.0
#13 0.556   Downloading argon2_cffi-21.3.0-py3-none-any.whl (14 kB)
#13 0.584 Collecting asgiref==3.5.2
#13 0.607   Downloading asgiref-3.5.2-py3-none-any.whl (22 kB)
#13 0.630 Collecting asttokens==2.0.5
#13 0.646   Downloading asttokens-2.0.5-py2.py3-none-any.whl (20 kB)
#13 0.670 Collecting attrs==21.4.0
#13 0.690   Downloading attrs-21.4.0-py2.py3-none-any.whl (60 kB)
#13 0.694      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 60.6/60.6 kB 26.3 MB/s eta 0:00:00
#13 0.711 Collecting backcall==0.2.0
#13 0.725   Downloading backcall-0.2.0-py2.py3-none-any.whl (11 kB)
#13 0.768 Collecting beautifulsoup4==4.11.1
#13 0.779   Downloading beautifulsoup4-4.11.1-py3-none-any.whl (128 kB)
#13 0.788      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 128.2/128.2 kB 16.7 MB/s eta 0:00:00
#13 0.812 Collecting bleach==5.0.1
#13 0.827   Downloading bleach-5.0.1-py3-none-any.whl (160 kB)
#13 0.832      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 160.9/160.9 kB 35.5 MB/s eta 0:00:00
#13 0.918 Collecting debugpy==1.6.2
#13 0.969   Downloading debugpy-1.6.2-py2.py3-none-any.whl (4.4 MB)
#13 1.062      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 4.4/4.4 MB 48.1 MB/s eta 0:00:00
#13 1.090 Collecting decorator==5.1.1
#13 1.103   Downloading decorator-5.1.1-py3-none-any.whl (9.1 kB)
#13 1.131 Collecting defusedxml==0.7.1
#13 1.156   Downloading defusedxml-0.7.1-py2.py3-none-any.whl (25 kB)
#13 1.184 Collecting django-extensions==3.2.0
#13 1.199   Downloading django_extensions-3.2.0-py3-none-any.whl (229 kB)
#13 1.207      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 229.1/229.1 kB 30.8 MB/s eta 0:00:00
#13 1.230 Collecting django-hashid-field==3.3.5
#13 1.251   Downloading django_hashid_field-3.3.5-py3-none-any.whl (19 kB)
#13 1.276 Collecting django-phonenumber-field==6.3.0
#13 1.299   Downloading django_phonenumber_field-6.3.0-py3-none-any.whl (65 kB)
#13 1.303      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 65.6/65.6 kB 28.1 MB/s eta 0:00:00
#13 1.322 Collecting django-rest-framework==0.1.0
#13 1.334   Downloading django-rest-framework-0.1.0.tar.gz (969 bytes)
#13 1.338   Preparing metadata (setup.py): started
#13 1.429   Preparing metadata (setup.py): finished with status &#39;done&#39;
#13 1.491 Collecting django==4.0.6
#13 1.504   Downloading Django-4.0.6-py3-none-any.whl (8.0 MB)
#13 1.664      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 8.0/8.0 MB 50.8 MB/s eta 0:00:00
#13 1.719 Collecting djangorestframework==3.13.1
#13 1.733   Downloading djangorestframework-3.13.1-py3-none-any.whl (958 kB)
#13 1.769      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 958.3/958.3 kB 27.2 MB/s eta 0:00:00
#13 1.798 Collecting entrypoints==0.4
#13 1.821   Downloading entrypoints-0.4-py3-none-any.whl (5.3 kB)
#13 1.849 Collecting et-xmlfile==1.1.0
#13 1.878   Downloading et_xmlfile-1.1.0-py3-none-any.whl (4.7 kB)
#13 1.910 Collecting executing==0.9.1
#13 1.922   Downloading executing-0.9.1-py2.py3-none-any.whl (16 kB)
#13 1.959 Collecting fastjsonschema==2.16.1
#13 1.982   Downloading fastjsonschema-2.16.1-py3-none-any.whl (22 kB)
#13 2.017 Collecting gunicorn==20.1.0
#13 2.050   Downloading gunicorn-20.1.0-py3-none-any.whl (79 kB)
#13 2.053      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 79.5/79.5 kB 40.6 MB/s eta 0:00:00
#13 2.080 Collecting hashids==1.3.1
#13 2.102   Downloading hashids-1.3.1-py2.py3-none-any.whl (6.6 kB)
#13 2.146 Collecting ipykernel==6.15.1
#13 2.161   Downloading ipykernel-6.15.1-py3-none-any.whl (132 kB)
#13 2.175      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.9/132.9 kB 9.7 MB/s eta 0:00:00
#13 2.203 Collecting ipython-genutils==0.2.0
#13 2.221   Downloading ipython_genutils-0.2.0-py2.py3-none-any.whl (26 kB)
#13 2.274 Collecting ipython==8.4.0
#13 2.290   Downloading ipython-8.4.0-py3-none-any.whl (750 kB)
#13 2.314      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 750.8/750.8 kB 32.1 MB/s eta 0:00:00
#13 2.349 Collecting jedi==0.18.1
#13 2.361   Downloading jedi-0.18.1-py2.py3-none-any.whl (1.6 MB)
#13 2.396      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.6/1.6 MB 46.9 MB/s eta 0:00:00
#13 2.434 Collecting jinja2==3.1.2
#13 2.446   Downloading Jinja2-3.1.2-py3-none-any.whl (133 kB)
#13 2.456      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 133.1/133.1 kB 14.5 MB/s eta 0:00:00
#13 2.489 Collecting jsonschema==4.7.2
#13 2.502   Downloading jsonschema-4.7.2-py3-none-any.whl (81 kB)
#13 2.510      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 81.1/81.1 kB 10.3 MB/s eta 0:00:00
#13 2.544 Collecting jupyter-client==7.3.4
#13 2.558   Downloading jupyter_client-7.3.4-py3-none-any.whl (132 kB)
#13 2.569      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 132.1/132.1 kB 13.8 MB/s eta 0:00:00
#13 2.605 Collecting jupyter-core==4.11.1
#13 2.624   Downloading jupyter_core-4.11.1-py3-none-any.whl (88 kB)
#13 2.628      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 88.4/88.4 kB 25.1 MB/s eta 0:00:00
#13 2.652 Collecting jupyterlab-pygments==0.2.2
#13 2.667   Downloading jupyterlab_pygments-0.2.2-py2.py3-none-any.whl (21 kB)
#13 2.729 Collecting markupsafe==2.1.1
#13 2.742   Downloading MarkupSafe-2.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (26 kB)
#13 2.774 Collecting matplotlib-inline==0.1.3
#13 2.791   Downloading matplotlib_inline-0.1.3-py3-none-any.whl (8.2 kB)
#13 2.815 Collecting mistune==0.8.4
#13 2.827   Downloading mistune-0.8.4-py2.py3-none-any.whl (16 kB)
#13 2.882 Collecting mysql-connector-python==8.0.30
#13 2.905   Downloading mysql_connector_python-8.0.30-py2.py3-none-any.whl (351 kB)
#13 2.912      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 351.6/351.6 kB 71.6 MB/s eta 0:00:00
#13 2.941 Collecting mysqlclient==2.1.1
#13 2.955   Downloading mysqlclient-2.1.1.tar.gz (88 kB)
#13 2.958      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 88.1/88.1 kB 36.4 MB/s eta 0:00:00
#13 2.969   Preparing metadata (setup.py): started
#13 3.055   Preparing metadata (setup.py): finished with status &#39;error&#39;
#13 3.058   error: subprocess-exited-with-error
#13 3.058
#13 3.058   × python setup.py egg_info did not run successfully.
#13 3.058   │ exit code: 1
#13 3.058   ╰─&gt; [16 lines of output]
#13 3.058       /bin/sh: 1: mysql_config: not found
#13 3.058       /bin/sh: 1: mariadb_config: not found
#13 3.058       /bin/sh: 1: mysql_config: not found
#13 3.058       Traceback (most recent call last):
#13 3.058         File &quot;&lt;string&gt;&quot;, line 2, in &lt;module&gt;
#13 3.058         File &quot;&lt;pip-setuptools-caller&gt;&quot;, line 34, in &lt;module&gt;
#13 3.058         File &quot;/tmp/pip-install-g9e2w1x3/mysqlclient_0c199296695d4759bc9418543288952d/setup.py&quot;, line 15, in &lt;module&gt;
#13 3.058           metadata, options = get_config()
#13 3.058         File &quot;/tmp/pip-install-g9e2w1x3/mysqlclient_0c199296695d4759bc9418543288952d/setup_posix.py&quot;, line 70, in get_config
#13 3.058           libs = mysql_config(&quot;libs&quot;)
#13 3.058         File &quot;/tmp/pip-install-g9e2w1x3/mysqlclient_0c199296695d4759bc9418543288952d/setup_posix.py&quot;, line 31, in mysql_config
#13 3.058           raise OSError(&quot;{} not found&quot;.format(_mysql_config_path))
#13 3.058       OSError: mysql_config not found
#13 3.058       mysql_config --version
#13 3.058       mariadb_config --version
#13 3.058       mysql_config --libs
#13 3.058       [end of output]
#13 3.058
#13 3.058   note: This error originates from a subprocess, and is likely not a problem with pip.
#13 3.059 error: metadata-generation-failed
#13 3.059
#13 3.059 × Encountered error while generating package metadata.
#13 3.059 ╰─&gt; See above for output.
#13 3.059
#13 3.059 note: This is an issue with the package mentioned above, not pip.
#13 3.059 hint: See above for details.</code></pre><p>처음에 검색해서 라이브러리 update 했더니 안됨
<code>× python setup.py egg_info did not run successfully.</code>
<code>poetry install setuptools</code></p>
<p>두번째 mysql_config 여기 프로젝트에서 mysql 데이터 이전 하는 것이기 때문에 </p>
<p><code>/bin/sh: 1: mysql_config: not found</code> 검색해서 
<a href="https://stackoverflow.com/questions/7475223/mysql-config-not-found-when-installing-mysqldb-python-interface">https://stackoverflow.com/questions/7475223/mysql-config-not-found-when-installing-mysqldb-python-interface</a>
해결책 발견!</p>
<p><code>RUN        apt -y install default-libmysqlclient-dev</code>
추가해줌 Dockerfile에</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Django Expressions]]></title>
            <link>https://velog.io/@django-support/Django-Expressions</link>
            <guid>https://velog.io/@django-support/Django-Expressions</guid>
            <pubDate>Sun, 18 Sep 2022 13:58:13 GMT</pubDate>
            <description><![CDATA[<h2 id="f-expressions">F() expressions</h2>
<h4 id="avoiding-race-conditions-using-f">Avoiding race conditions using F()</h4>
<p>python이 아닌 데이터베이스에서 필드값을 update하면 F() 는 race condition을 피할 수 있다.</p>
<p>예시)
만약 2개의 python threads가 코들르 실행한다면, 다른 한 thread가 데이터 베이스로부터 field 값을 조회 한 후, 다른 하나의 thread는 field 값을 조회, 증가, 그리고 저장 할 수 있습니다. 다른 하나의 thread가 기존의 값을 바탕으로 한 저장한 값; 첫번째 thread 작업은 손실 될것이다. </p>
<p>만약 그 데이터 베이스가 그 field값을 책을 진다면, 그 process는 더욱 강력합니다. save(), update() 함수를 실행할때, 데이터 베이스에 그 field 값을 기반으로 한 그 field만 항상 update 것 입니다.** 인스턴스가 조회 되었을때 값을 기반으로 하지 않습니다**.(인스턴스에 캐쉬된 값을 기반으로 하지 않는다는 것 같다)</p>
<h4 id="f-assignments-persist-after-modelsave">F() assignments persist after Model.save()</h4>
<p>F() 모델 fields에 할당된 objects는 model instance를 저장한 후에 지속된다 그리고 각각 save() 함수에 적용 될 것이다.  </p>
<pre><code class="language-python">reporter = Reporters.objects.get(name=&#39;Tintin&#39;)
reporter.stories_filed = F(&#39;stories_filed&#39;) + 1
reporter.save()

reporter.name = &#39;Tintin Jr.&#39;
reporter.save()</code></pre>
<p>stories_field는 이러한 경우에 두번 update 될것이다. 처음 1이었다면 마지막 값은 3일 것이다.
이러한 persistence는 그것을 저장한 후에 model objects를 reloading 함으로써 피할수 있다.
refresh_from_db() 사용함으로써</p>
<h4 id="using-f-in-filters">Using F() in filters</h4>
<p>F()는 QuerySet에 유용하다, Python 값이 아닌 그들의 field 값에 기반한 기준에 따른 a set of objects를 filter 할 수 있다.</p>
<h4 id="using-f-with-annotations">Using F() with annotations</h4>
<p>F()는 다른 필드들과 산술하여 결합함으로써 model 에 동적 필드를 생성되어 질수 있다.</p>
<pre><code class="language-python">company = Company.objects.annotate(
chairs_needed=F(&#39;num_employees&#39;) - F(&#39;num_chairs&#39;))</code></pre>
<p>만약 다른 유형들을 결합한 그 fields는 Django에게 어떤 종류의 필드가 반환 될것인지 말할 필요가 있다.
F()는 output_field를 직접적으로 지원하지 않으므로 당신은 ExpressionWrapper로 expression을 감쌀 필요가 있다.</p>
<pre><code class="language-python">from django.db.models import DateTimeField, ExpressionWrapper, F

Ticket.objects.annotate(
    expires=ExpressionWrapper(
        F(&#39;active_at&#39;) + F(&#39;duration&#39;), output_field=DateTimeField()
    )
)</code></pre>
<p>ForeignKey와 같은 관계 fieldsfmf 참조 할때, F()는 model instance보다 primary key를 반환한다.</p>
<pre><code class="language-shell">&gt;&gt; car = Company.objects.annotate(built_by=F(&#39;manufacturer&#39;))[0]
&gt;&gt; car.manufacturer
&lt;Manufacturer: Toyota&gt;
# id 값을 반환함
&gt;&gt; car.built_by
3</code></pre>
<h4 id="using-f-to-sort-null-values">Using F() to sort null values</h4>
<p>a field&#39;s null values 의 순서를 조정하기 위해서 Expression.asc() or desc() 에 nulls_first or nulls_last키워드 인수 그리고 F()를 사용해라.</p>
<p>예시, nulls_last=True 인 값 반대로? (?????????? 직접 봐야 알것 같음</p>
<pre><code class="language-python">from django.db.models import F
Company.objects.order_by(F(&#39;last_contaced&#39;).desc(nulls_last=True))</code></pre>
<h2 id="func-expressions">Func() expressions</h2>
<p>Func() expressions는 데이터베이스 functions를 포함시킨 모든 expressions의 기본 type 이다.</p>
<pre><code class="language-python">from djnaog.db.models import F, Func

queryset.annotate(field_lower=Func(F(&#39;field&#39;), function=&#39;LOWER&#39;))</code></pre>
<p>or Func() expressions( like COALESCE, LOWER)는 데이터 베이스 functions의 라이브러리를 build하는데 이용되고 있다.</p>
<pre><code class="language-python">class Lower(Func):
    function = &#39;LOWER&#39;
queryset.annotate(field_lower=Lower=(&#39;field&#39;))</code></pre>
<p>그러나 두 경우 모두 각 모델은 다음에 오는 SQL문으로부터 생상된 추가 속성 field_lower로 annotated 된 하나의 queryset으로 결과가 나타날 것이다.
내장 데이터베이스 함수들의 목록에 대해 Database Functions를 보라</p>
<p>The Func API는 다음과 같습니다.</p>
<p>class Func(<em>expressions, *</em>extra)</p>
<p><strong>function</strong></p>
<p>class 속성, 문자 형식(characterfield 의미하는거 같음), this function을 생성되어진 SQL을 설명하는. 기본은 &#39;%(function)s(%(expressions)s)&#39;.</p>
<p>???????????????????????????????
만약 당신이 strftime(&#39;%W&#39;, &#39;date&#39;) 과 같은 SQL을 구성한다면 그리고 쿼리의 리터럴 % 문자를 필요로 한다면, template 속성에서 4배 (%%%%) 이다 그 문자는 두배 보관되어지기 때문이다. as_sql()에서 ?template보관 동안에 한번 그리고 데이터베이스 커서에서 쿼리 파라미터를 가진 SQL 보관 에서 한번</p>
<p><strong>arg_joiner</strong>
expressions 리트스를 join하는데 사용되는 문자열을 나타내는 하나의 클래스 속성. 기본값은 &#39;,&#39;입니다.</p>
<p><strong>arity</strong>
the function이 수락하는 인수의 숫자를 나타내는 하나의 클래스 속성. 만약 이 속성이 set 이고 the function이  다른 수의 expressions으로 호출되어진다면, TypeError는 발생할것이다 기본갑슨 None</p>
<p><strong>as_sql(compiler, connection, cuntion=None, template=None, arg_joiner=None,</strong> <strong>**extra_context)</strong></p>
<p>데이터베이스 function에 대한 SQL fragment를 생성시켜라. 나타낸다 (sql, params) 튜플, sql이 SQL string, 그리고 params 쿼리 파라미터 튜플 혹은 리스트 이다.</p>
<p>The as_vendor() methods는 function, template, arg_joiner, 그리고 다른 ***<em>extra_context *</em> 필요에 따라 customize 하기 위한 parameters(매개변수)를 사용한다.</p>
<ul>
<li>as needed : 필요에 따라</li>
</ul>
<pre><code class="language-python">class ConcatPair(Func):
    ...
    function = &#39;CONCAT&#39;
    ...

    def as_mysql(self, compiler, connection, **extra_context):
        return super().as_sql(
            compiler, connection,
            function=&#39;CONCAT_WS&#39;,
            template=&quot;%(function)s(&#39;&#39;, %(expressions)s)&quot;,
            **extra_context
        )</code></pre>
<p>SQL injection 취약성을 피하기 위해 extra_context는 신뢰되지 않는 user 입력을 포함해서는 안됩니다  rather than 데이터메이스 driver가 이것들을 빠져나가는 쿼리 매개변수로써 전달 되어진기 보다 이러한 값들은 SQL string에 보관되어 진다.</p>
<p>The *expressions 인수는 그 함수가 적용되어질 예정인 expressions list 위치인자 이다.
The expressions는 arg_joiner와 함께 결합된 문자열로 변환 됩니다. 그리고 expresions 자리표시자로써 template에 보관 됩니다.</p>
<p>위치인자들은 python 값들 혹은 expressions 될수 있다. 문자열은 column 참조로 추정되고 F() expressions로 감싸질것이다. 다른 값들이 Value() expressions에 감싸지는 반면에.</p>
<p>the <strong>**extra</strong> kwargs는 template 속성에 보관되어진 key=value 이다. </p>
<p>the function, template, and arg_joiner 키워드들은 같은 이름의 속성들을 대체될 수 있다 your 자신의 class 정의 없이.
output_field는 예상되는 반환되는 type을 정의하는데 사용 할수 있다.</p>
<h2 id="aggregate-expressions">Aggregate() expressions</h2>
<p>aggregate expression은 GROUP BY 절이 필요로 하는 the query를 알려주는 Func() expression 의 특별한 case이다. 모든 aggregate functions, SUM() and Count(), Aggregate()로 부터 상속받은.</p>
<p>Aggregates는 expressions 그리고 expressions을 감싸함으로 you는 몇몇 복잡한 계산을 나타낼 수 있다.</p>
<pre><code class="language-python">from django.db.models import Count

Company.objects.annotate(
    managers_required=(Count(&#39;num_employees&#39;) / 4) + Count(&#39;num_managers&#39;))</code></pre>
<p>the Aggregate API 는 필요에 따라:</p>
<p><strong>class Aggregate(*expressions, output_field=None, distinct=False, filter=None, default=None,</strong> <strong>**extra)</strong></p>
<p><strong>function</strong>
생성되는 aggregate function을 설명하는 a class 속성, the function은 the function placeholder로써 보관 되어 질것이다 template 안에. function=None(Default)</p>
<p><strong>window_compatible</strong>
window_compatible=True(Default), 대부분 aggregate functions는 source expressions으로 사용할 수 있습니다.</p>
<p><strong>allow_distinct</strong>
하나의 클래스 속성은 고유한 키워드 인수를 전달하는 것이 허용 가능한지 여부를 결정한다.
만약 allow_distinct=False(default), TypeError가 발생된다 만약 distinct=True가 전달 된다면.</p>
<p><strong>empty_result_set_value</strong>
empty_result_set_value=None(Default), 대부분 aggregate functions는 null를 결과로 나타낸다. empty 결과값을 에 적용 될때.</p>
<p>The expressions 위치 인자들은 model field의 변형 혹은 model fiels의 이름들은 expressions를 포함시킬수 있다. 그들은 strin으로 변환될 것이다 그리고 expressions placeholder로써 사용될 것이다. template 안에서.</p>
<p>The output_field 인자는 IntegerField() or BooleanField(0와 같은 model field instance를 필요로 하며, Django는 데이터 베이스로 부터 조회한 후에 값을 불러온 후, 이 인스턴스에 값을 로드합니다. 보통 arguments는 필요하지 않습니다 데이터 유효성 검사와 관련된 인수로 모델 필드를 인스턴스화 할때,</p>
<p>Django가 어떤 필드 타입 결과가 되어야만 하는지를 결정할수 있을때, Note that output_field만 요구 되어 진다. 복잡한 expressions는 mix field 유형은 원하는 output_field를 정의 해야만한다. 예를들어, IntegerField() 와 FloatField()는 함께 추가하면 output_field=FloatField()가 정의 되어 있어야만 합니다.</p>
<p>고유의 인자는 aggregate function가 각각 expressions의 고유 값을 호출 해야하는지 여부를 결정한다.인자는 allow_distinct=True 설정을 가진 aggregate에서만 지원 받는다.</p>
<p>filter 인자는 집계 되는 row를 filter하는데 사용되는 Q object를 취한다. 조건 집계 와 annotaions 필터 예시 사용</p>
<p>기본 인자는 통합에 집계와 함께 Coalesce에 전달될 값을 사용합니다. 이것은 queryset이 아무 항목이 포함되지 않았을때 None이외의 값을 반환하도록 지정하는데 유용하다.</p>
<h2 id="creating-your-own-aggregate-functions">Creating your own Aggregate Functions</h2>
]]></description>
        </item>
        <item>
            <title><![CDATA[git hub ssh 설정]]></title>
            <link>https://velog.io/@django-support/git-hub-ssh-%EC%84%A4%EC%A0%95</link>
            <guid>https://velog.io/@django-support/git-hub-ssh-%EC%84%A4%EC%A0%95</guid>
            <pubDate>Tue, 30 Aug 2022 04:51:47 GMT</pubDate>
            <description><![CDATA[<p>ssh key 생성하기</p>
<p><code>ssh-keygen -t rsa -C &quot;{github 등록된 email}&quot;</code></p>
<p>계속 enter</p>
<p><img src="https://velog.velcdn.com/images/django-support/post/87056374-5fb0-47bc-b3af-7119966adc0e/image.png" alt=""></p>
<p>공개키 print
<code>$ cat ~/.ssh/id_rsa.pub</code></p>
<p>전부 복사해서 github 등록하기</p>
<p>vi ~/.ssh/config 구현</p>
<pre><code class="language-shell">IgnoreUnknown UseKeychain
UseKeychain yes</code></pre>
<pre><code class="language-shell"># 생성이 완료되었으면 PC에 잘 generate 되었는지 터미널에서 확인해보자.
ubuntu@ip-172-31-4-222:~$ ssh -T git@github.com
/home/ubuntu/.ssh/config: line 3: Bad configuration option: usekeychain
/home/ubuntu/.ssh/config: terminating, 1 bad configuration options</code></pre>
<p><img src="https://velog.velcdn.com/images/django-support/post/38975f3f-fae6-4859-ab6f-e1596360b747/image.png" alt=""></p>
<p><a href="https://stackoverflow.com/questions/65876442/how-to-connect-ssh-key-and-fix-bad-configuration-option-ssh-ed25519">https://stackoverflow.com/questions/65876442/how-to-connect-ssh-key-and-fix-bad-configuration-option-ssh-ed25519</a>
<a href="https://devocean.sk.com/blog/techBoardDetail.do?ID=163311">https://devocean.sk.com/blog/techBoardDetail.do?ID=163311</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[pycharm 사용법]]></title>
            <link>https://velog.io/@django-support/pycharm-%EC%82%AC%EC%9A%A9%EB%B2%95</link>
            <guid>https://velog.io/@django-support/pycharm-%EC%82%AC%EC%9A%A9%EB%B2%95</guid>
            <pubDate>Tue, 26 Jul 2022 22:19:43 GMT</pubDate>
            <description><![CDATA[<p>Pycharm </p>
<ul>
<li>Code &gt; Inspector Code 통해서 코드 오류 잡을수 있음</li>
<li>Shift + Command + F 전체 검색</li>
<li>Show Options Menu &gt; Tree Appearance &gt; ??how to show method 
Ctrl + Alt + L : Code format ( 코드 자동 정렬 )
Ctrl + Alt + Shift + L : Whole file Code format 
Ctrl + Alt + O : Import 정리</li>
</ul>
<p>출처: <a href="https://cardin.tistory.com/entry/%ED%8C%8C%EC%9D%B4%EC%B0%B8-%EB%8B%A8%EC%B6%95%ED%82%A4-%EB%AA%A8%EC%9D%8C-PyCharm-%EB%8B%A8%EC%B6%95%ED%82%A4-1">https://cardin.tistory.com/entry/파이참-단축키-모음-PyCharm-단축키-1</a> [人生襍多:티스토리]</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[django rest framework User model 만들기]]></title>
            <link>https://velog.io/@django-support/django-rest-framework-User-model-%EB%A7%8C%EB%93%A4%EA%B8%B0</link>
            <guid>https://velog.io/@django-support/django-rest-framework-User-model-%EB%A7%8C%EB%93%A4%EA%B8%B0</guid>
            <pubDate>Fri, 29 Apr 2022 05:31:08 GMT</pubDate>
            <description><![CDATA[<h2 id="user">User</h2>
<p>화면 </p>
<p><img src="https://velog.velcdn.com/images/django-support/post/5bcbe717-fad3-4414-a271-f380ad14e5f9/image.png" alt=""></p>
<p><code>Models.py</code></p>
<pre><code class="language-python">
from django.db import models
from django.contrib.auth.models import (BaseUserManager, AbstractUser)
from django.utils.translation import ugettext_lazy as _
from phonenumber_field.modelfields import PhoneNumberField


class UserManager(BaseUserManager):
    # password=None으로 놓는데 그 이유를 모르겠다.
    # **extra_fields 값을 통해서 나머지 값들이 들어감
    def create_user(self, email, username, password, **extra_fields):
        &quot;&quot;&quot;
        주어진 이메일, 닉네임, 비밀번호 등 개인정보로 User 인스턴스 생성
        &quot;&quot;&quot;
        if not email:
            raise ValueError(_(&quot;Users must have an email address&quot;))
        username = self.model.normalize_username(username)
        user = self.model(
            email=self.normalize_email(email),
            username=username,
            **extra_fields
        )
        user.is_active = False
        user.is_staff = False
        user.is_superuser = False
        user.set_password(password)
        user.save(using=self._db)
        return user

    # **extra_fields 값을 통해서 나머지 값들이 들어감
    def create_superuser(self, email, username, password, **extra_fields):
        &quot;&quot;&quot;
        주어진 이메일, 닉네임, 비밀번호 등 개인정보로 User 인스턴스 생성
        단, 최상위 사용자이므로 권한을 부여한다.
        &quot;&quot;&quot;
        user = self.create_user(
            email=email,
            username=username,
            password=password,
            **extra_fields

        )
        user.is_active = True
        user.is_staff = True
        user.is_admin = True
        user.is_superuser = True
        user.level = 100
        user.save(using=self._db)
        return user


class User(AbstractUser):
    email = models.EmailField(
        verbose_name=_(&#39;Email address&#39;),
        max_length=255,
        unique=True,
    )
    username = models.CharField(
        verbose_name=_(&#39;username&#39;),
        max_length=30,
        unique=True
    )
    company = models.CharField(
        verbose_name=_(&#39;company name&#39;),
        max_length=30,
        blank=True,
        null=True)
    advertisement_url = models.CharField(
        verbose_name=_(&#39;광고 URL &#39;),
        max_length=255,
        blank=True,
        null=True)
    level = models.IntegerField(
        verbose_name=_(&#39;user level&#39;),
        default=0)
    unique_id = models.CharField(
        verbose_name=_(&#39;google Id&#39;),
        max_length=50,
        blank=True)
    mobile = PhoneNumberField(
        verbose_name=_(&#39;mobile phone number&#39;),
        unique=True,
        null=False,
        blank=False,
        max_length=30, )

    naver_api_key = models.CharField(
        verbose_name=_(&#39;naver api Key&#39;),
        max_length=255,
        blank=True,
        null=True,
        unique=True)
    is_active = models.BooleanField(
        verbose_name=_(&#39;Is active&#39;),
        default=False
    )
    is_admin = models.BooleanField(
        verbose_name=_(&#39;Is admin&#39;),
        default=False
    )
    created_at = models.DateTimeField(
        verbose_name=_(&#39;Date joined&#39;),
        auto_now_add=True
    )
    updated_at = models.DateTimeField(
        verbose_name=_(&#39;Date updated&#39;),
        auto_now=True
    )

    objects = UserManager()
    # 로그인할때 email 이용 
    USERNAME_FIELD = &#39;email&#39;
    # 필수 데이터 입력 
    REQUIRED_FIELDS = [&#39;username&#39;, &#39;mobile&#39;,]

    class Meta:
        verbose_name = &#39;유저&#39;
        verbose_name_plural = &#39;%s 목록&#39; % verbose_name
        ordering = (&#39;-date_joined&#39;,)

    def __str__(self):
        return f&#39;{self.email}&#39;
</code></pre>
<p><code>serializers.py</code></p>
<pre><code class="language-python">from rest_framework import serializers

from members.models import User

# user list serializer 
class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = &quot;__all__&quot;

</code></pre>
<p><code>apis.py</code></p>
<pre><code class="language-python">
from rest_framework import generics

from members.models import User
from members.serializers import UserSerializer


class UserList(generics.ListAPIView):
    queryset = User.objects.all()
    serializer_class = UserSerializer
</code></pre>
<p><code>urls.py</code></p>
<pre><code class="language-python">from django.urls import path

from members.apis import UserList

urlpatterns = [
    path(&#39;&#39;, UserList.as_view(), name=&quot;user-list&quot;)
]</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[자료구조 with python]]></title>
            <link>https://velog.io/@django-support/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0%EC%9D%98-%EC%9D%B4%ED%95%B4-with-python-%EB%A6%AC%EB%B7%B0</link>
            <guid>https://velog.io/@django-support/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0%EC%9D%98-%EC%9D%B4%ED%95%B4-with-python-%EB%A6%AC%EB%B7%B0</guid>
            <pubDate>Mon, 25 Apr 2022 07:53:18 GMT</pubDate>
            <description><![CDATA[<h1 id="01-자료구조를-배우기-위한-준비">01 자료구조를 배우기 위한 준비</h1>
<h3 id="12-수행시간의-분석">1.2 수행시간의 분석</h3>
<p>자료구조에 대한 연산 수행 시간 측정 방식 = 알고르지므 성능을 측정하는 방식 </p>
<p>알고리즘 성능 </p>
<p>1) 수행시간 : 시간복잡도(Time Complexity)
2) 메모리 공간의 크기 : 공간복잡도(Space Complexity)</p>
<p>알고리즘의 성능은 실제 소요된 시간을 의미한다.
(그러나, 프로그래머의 숙련도, 프로그래밍 언어의 종류, 컴퓨터 성능에 따라 수행시간이 달라져 객과적 평가하기 힘들다)</p>
<p>수행시간(시간복잡도)는 기본적으로 연산횟수를 입력크기의 함수로 나타낸다</p>
<p><strong>기본연산(Elementary Operation)이란 데이터간 크기비교, 데이터 읽기 및 갱신, 숫자 계산 등과 같은 단순한 연산을 의미한다.</strong></p>
<p>출저: 자료구조의 이해 with python 책
<a href="https://www.aladin.co.kr/shop/wproduct.aspx?ItemId=128681094">https://www.aladin.co.kr/shop/wproduct.aspx?ItemId=128681094</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[마켓컬리 주소지 관리]]></title>
            <link>https://velog.io/@django-support/%EB%A7%88%EC%BC%93%EC%BB%AC%EB%A6%AC-%EC%A3%BC%EC%86%8C%EC%A7%80-%EA%B4%80%EB%A6%AC</link>
            <guid>https://velog.io/@django-support/%EB%A7%88%EC%BC%93%EC%BB%AC%EB%A6%AC-%EC%A3%BC%EC%86%8C%EC%A7%80-%EA%B4%80%EB%A6%AC</guid>
            <pubDate>Wed, 30 Mar 2022 07:10:36 GMT</pubDate>
            <description><![CDATA[<h2 id="배송지-remove-기능-구현">배송지 Remove 기능 구현</h2>
<h3 id="frontend">Frontend</h3>
<p>lib/api/address.py</p>
<pre><code class="language-javascript">import axios from &#39;axios&#39;;

const client = axios.create();

export const removeAddress = (id) =&gt; {
    return client.delete(`/members/address/${id}/detail/`, {
        headers: {
            Authorization: `Token ${sessionStorage.getItem(&#39;token&#39;)}`,
        },
    });
};</code></pre>
<p>lib/loading.py</p>
<pre><code class="language-javascript">import { createAction, handleActions } from &#39;redux-actions&#39;;

const START_LOADING = &#39;loading/START_LOADING&#39;;
const FINISH_LOADING = &#39;loading/FINISH_LOADING&#39;;

export const startLoading = createAction(
    START_LOADING,
    (requestType) =&gt; requestType,
);

export const finishLoading = createAction(
    FINISH_LOADING,
    (requestType) =&gt; requestType,
);

const initialState = {};

const loading = handleActions(
    {
        [START_LOADING]: (state, action) =&gt; ({
            ...state,
            [action.payload]: true,
        }),
        [FINISH_LOADING]: (state, action) =&gt; ({
            ...state,
            [action.payload]: false,
        }),
    },
    initialState,
);
export default loading;

</code></pre>
<p>lib/createRequestSaga.py</p>
<pre><code class="language-javascript">
import { call, put } from &#39;redux-saga/effects&#39;;
import { startLoading, finishLoading } from &#39;../modules/loading&#39;;

export const createRequestActionTypes = (type) =&gt; {
    const SUCCESS = `${type}_SUCCESS`;
    const FAILURE = `${type}_FAILURE`;
    return [type, SUCCESS, FAILURE];
};

export default function createRequestSaga(type, request) {
    const SUCCESS = `${type}_SUCCESS`;
    const FAILURE = `${type}_FAILURE`;

    return function* (action) {
        yield put(startLoading(type));
        try {
            const response = yield call(request, action.payload);
            console.log(response.data)
            yield put({
                type: SUCCESS,
                payload: response.data,
            });
        } catch (e) {
            yield put({
                type: FAILURE,
                payload: e,
                error: true,
            });
        }
        yield put(finishLoading(type));
    };
}

</code></pre>
<p>modules/address.py</p>
<pre><code class="language-javascript">
import { createAction, handleActions } from &#39;redux-actions&#39;;
import { takeLatest } from &#39;redux-saga/effects&#39;;
import * as addressAPI from &#39;../lib/api/address&#39;;
import createRequestSaga, {
    createRequestActionTypes,
} from &#39;../lib/createRequestSaga&#39;;


const [REMOVE_ADDRESS, REMOVE_ADDRESS_SUCCESS, REMOVE_ADDRESS_FAILURE] =
    createRequestActionTypes(&#39;address/REMOVE_ADDRESS&#39;);


export const removeAddress = createAction(REMOVE_ADDRESS, (id) =&gt; id);

const removeAddressSaga = createRequestSaga(
    REMOVE_ADDRESS,
    addressAPI.removeAddress
)

export function* addressSaga() {
    yield takeLatest(REMOVE_ADDRESS, removeAddressSaga)
}</code></pre>
<pre><code class="language-javascript">
import React, { useCallback, useEffect } from &#39;react&#39;;
import { useDispatch, useSelector } from &#39;react-redux&#39;;
import { useNavigate } from &#39;react-router&#39;;
import CartComponent from &#39;../../components/cart/CartComponent&#39;;
import {
    updateAddress,
} from &#39;../../modules/address&#39;;

const CartContainer = () =&gt; {
    const dispatch = useDispatch();
    const navigate = useNavigate();

  const onRemoveAddress = useCallback(
        (id) =&gt; {
            try {
                dispatch(removeAddress(id));
            } catch (e) {
                console.log(e);
            }
            navigate(0);
        },
        [dispatch],
    );

  return (
        &lt;CartComponent
            onRemoveAddress={onRemoveAddress}
        /&gt;
    );
};</code></pre>
<pre><code class="language-javascript">import React from &#39;react&#39;;
const CartComponent = ({onRemoveAddress}) =&gt; {

  return (

    &lt;button 
          className=&quot;delete-btn&quot;
          onClick={() =&gt; onDeletePostCodeDetailInfo(id)}&gt;삭제&lt;/button&gt;
  )

};</code></pre>
<h3 id="backend">Backend</h3>
<p>url.py</p>
<pre><code class="language-python">path(&#39;address/&lt;int:address_id&gt;/detail/&#39;, AddressDetailAddressUpdateAPIView.as_view())</code></pre>
<p>model.py</p>
<pre><code class="language-python">class UserAddress(models.Model):
    user = models.ForeignKey(&#39;User&#39;, on_delete=models.CASCADE, related_name=&#39;user_addresses&#39;, help_text=&#39;유저 주소&#39;)
    address = models.CharField(&#39;주소&#39;, max_length=255)
    default_address = models.BooleanField(&#39;기본배송지 여부&#39;, default=False)
    selected_address = models.BooleanField(&#39;선택된 배송지 여부&#39;, default=True)
    phone_number = models.CharField(&#39;휴대폰 주소&#39;, max_length=13, default=&#39;&#39;)
    receive_name = models.CharField(&#39;받은사람&#39;, max_length=50, default=&#39;&#39;)
    created = models.DateTimeField(&#39;주소 추가 날짜&#39;, auto_now_add=True)
    updated_at = models.DateTimeField(&#39;주소 변경 날짜&#39;, auto_now=True)</code></pre>
<p>serializer.py</p>
<pre><code class="language-python">class UserDetailAddressUpdateSerializer(serializers.ModelSerializer):
    user = UserSerializer(read_only=True, required=False)

    class Meta:
        model = UserAddress
        fields = &quot;__all__&quot;</code></pre>
<p>api.py</p>
<pre><code class="language-python">class AddressDetailAddressUpdateAPIView(generics.RetrieveUpdateDestroyAPIView):
    permission_classes = (IsAuthenticated,)
    queryset = UserAddress.objects.all()
    serializer_class = UserDetailAddressUpdateSerializer

    def get_object(self):
        obj = get_object_or_404(UserAddress, pk=self.kwargs.get(&quot;address_id&quot;))
        return obj
    def delete(self, request, *args, **kwargs):
        return self.destroy(request, *args, **kwargs)

    def perform_destroy(self, instance):
        queryset = self.queryset.filter(user=self.request.user)
        extra_objects = queryset.exclude(id=instance.id)
        if len(extra_objects) &lt; 1:
            pass
        else:
            if instance.default_address and instance.selected_address:
                obj = extra_objects.first()
                obj.default_address = True
                obj.selected_address = True
                obj.save()

            elif instance.default_address and instance.selected_address is False:
                # 기본 주소지 is True &amp;&amp; 선택 주소지 is False
                # 선택 주소지 filtering, default address 설정
                obj_filter = [add_obj for add_obj in extra_objects if add_obj.selected_address is True]
                obj = obj_filter.pop()
                obj.default_address = True
                obj.save()
            elif instance.default_address is False and instance.selected_address:
                # 기본 주소지 is False &amp;&amp; 선택 주소지 is True
                # 선택 주소지 filtering, default address selected address = True 설정
                obj_filter = [add_obj for add_obj in extra_objects if add_obj.default_address is True]
                obj = obj_filter.pop()
                obj.selected_address = True
                obj.save()
            else:
                pass
        super().perform_destroy(instance)
</code></pre>
<p>주소지를 제거할때 
기본주소지(default_address) 와 선택주소지(selected_address)를 고려하여 주소 object를 제거 후에 어떻게 나머지 값들을 처리할지 구상하였다.</p>
<p>먼저!!</p>
<ul>
<li>주소가 2개 이상인 경우</li>
<li>주소가 1개라면 just remove object</li>
</ul>
<p>a. 주소가 2개 이상일 경우
*<em>1) 기본 주소지 이면서 선택 주소지가 True인 객체를 제거 할 경우
*</em>
<img src="https://images.velog.io/images/django-support/post/307245f8-1fb4-4a2a-a43b-c2597db40225/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202022-03-30%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%203.59.00.png" alt=""></p>
<p>결과물</p>
<ul>
<li>다음 index 객체의 기본주소지 선택주소지 값을 모두 True로 설정하기
<img src="https://images.velog.io/images/django-support/post/f8c5e9d8-3c9e-465e-9ef4-3870545d8e6c/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202022-03-30%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%204.00.36.png" alt=""></li>
</ul>
<p>*<em>2) 기본 주소지 True AND 선택 주소지 False인 객체를 제거할 경우
*</em></p>
<p><img src="https://images.velog.io/images/django-support/post/dd5b4b54-48b1-46c5-a87e-d55d865e48b7/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202022-03-30%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%204.01.45.png" alt=""></p>
<p>결과물</p>
<ul>
<li>기본 주소지 True인 값을 선택 주소지로 설정
<img src="https://images.velog.io/images/django-support/post/b4a8848b-0514-419a-ab6e-a66022188e78/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202022-03-30%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%204.02.16.png" alt=""></li>
</ul>
<p><strong>3) 기본 주소지 False AND 선택 주소지 True인 객체를 제거할 경우</strong></p>
<p><img src="https://images.velog.io/images/django-support/post/c1de18a2-4b25-4a0a-ba06-3086da24381a/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202022-03-30%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%204.03.31.png" alt=""></p>
<p>결과물</p>
<ul>
<li>선택 주소지 True인 값을 기본 주소지로 설정
<img src="https://images.velog.io/images/django-support/post/93376a55-8489-4c38-b59f-16138a1d4474/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202022-03-30%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%204.04.44.png" alt=""></li>
</ul>
<p><strong>4) 기본 주소지 AND 선택주소지 모두 False인 객체를 제거할 경우</strong></p>
<p><img src="https://images.velog.io/images/django-support/post/3172b4e7-0793-4f6c-9bd6-8a3a3079afbd/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202022-03-30%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%204.09.16.png" alt="">
결과물</p>
<ul>
<li>그냥 제거</li>
</ul>
<p><img src="https://images.velog.io/images/django-support/post/4d2de472-6f15-4dbf-81bd-4bc370fd7425/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202022-03-30%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%204.09.38.png" alt=""></p>
<p>from source 
<a href="https://github.com/velopert/learning-react/">https://github.com/velopert/learning-react/</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[DRF UpdateView Error]]></title>
            <link>https://velog.io/@django-support/DRF-UpdateView-Error</link>
            <guid>https://velog.io/@django-support/DRF-UpdateView-Error</guid>
            <pubDate>Wed, 30 Mar 2022 06:19:50 GMT</pubDate>
            <description><![CDATA[<p>generics.RetrieveUpdateDestroyAPIView</p>
<p>APIView 부분 업데이트를 하기 위해서 고생좀 했다.
요즘 react 프레임워크를 다루면서 request를 내 편의대로 보내다보니
생기는 error였다. 
backend만 했을때 정확한 데이터 필수값대로 보내세요 라고 document만 보내주면 이런 고민할 계기도 없었을 텐데 frontend 입장에서 내 편의대로 보내다보니 이런 error가 생겼던거 같기도 하지만 결정적으로는 내 오타...문제다..</p>
<p><img src="https://images.velog.io/images/django-support/post/f5cc2db7-e441-4e44-8e6f-6081ee1e036a/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202022-03-25%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%2012.37.27.png" alt=""></p>
<pre><code>File &quot;/Users/kimdoo/.pyenv/versions/youtube-backend-env/lib/python3.9/site-packages/rest_framework/mixins.py&quot;, line 66, in update
    serializer = self.get_serializer(instance, data=request.data, partial=partial)
AttributeError: &#39;AddressUpdateAPIView&#39; object has no attribute &#39;data&#39;</code></pre><p>이런 버그가 생겼다.</p>
<p>말이 안되지 않는가? 
request.data  data 값이 없다니!!! ...</p>
<pre><code>import axios from &#39;axios&#39;;

const client = axios.create();

export const updateAddress = ({ id, selected_address }) =&gt; {
    return client.put(
        `/members/address/${id}/`,
        { selected_address},
        {
            headers: {
                Authorization: `Token ${sessionStorage.getItem(&#39;token&#39;)}`,
            },
        },
    );
};

</code></pre><p>알고보니 </p>
<pre><code class="language-python">def put(self, request, *args, **kwargs):
    return self.partial_update(self, request, *args, **kwargs)
</code></pre>
<p><code>self</code> 파라미터를 추가해줘서 error가 발생한 거였음</p>
<pre><code class="language-python">
def put(self, request, *args, **kwargs):
    return self.partial_update(request, *args, **kwargs)</code></pre>
<p>에러 해결!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[리액트 배포 버그(1)]]></title>
            <link>https://velog.io/@django-support/%EB%A6%AC%EC%95%A1%ED%8A%B8-%EB%B0%B0%ED%8F%AC-%EB%B2%84%EA%B7%B81</link>
            <guid>https://velog.io/@django-support/%EB%A6%AC%EC%95%A1%ED%8A%B8-%EB%B0%B0%ED%8F%AC-%EB%B2%84%EA%B7%B81</guid>
            <pubDate>Fri, 31 Dec 2021 00:55:14 GMT</pubDate>
            <description><![CDATA[<h1 id="header가-사라짐">Header가 사라짐</h1>
<h3 id="username">username??</h3>
<p><img src="https://images.velog.io/images/django-support/post/871ee5ab-fcdf-4c32-a93e-693acf3470ba/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7,%202021-12-31%2009-54-44.png" alt=""></p>
<p><code>yarn start</code>
yarn 으로 개발 서버 실행하면 페이지가 문제 없이 나타남</p>
<p><img src="https://images.velog.io/images/django-support/post/a488c7c9-5dcc-4364-b080-1f6d10bdf455/Homepage.png" alt=""></p>
<p><code>yarn run build</code>
<code>npx serve -s build</code>
빌드 후 실행해 보면 아무 페이지도 나타나지 않음 </p>
<p>react-router-dom 문제라고 추정중</p>
<p>문제 해결 다음 게시글에서...</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[쿠팡 파트너스 회원가입]]></title>
            <link>https://velog.io/@django-support/%EC%BF%A0%ED%8C%A1-%ED%8C%8C%ED%8A%B8%EB%84%88%EC%8A%A4-%ED%9A%8C%EC%9B%90%EA%B0%80%EC%9E%85</link>
            <guid>https://velog.io/@django-support/%EC%BF%A0%ED%8C%A1-%ED%8C%8C%ED%8A%B8%EB%84%88%EC%8A%A4-%ED%9A%8C%EC%9B%90%EA%B0%80%EC%9E%85</guid>
            <pubDate>Fri, 24 Dec 2021 06:32:59 GMT</pubDate>
            <description><![CDATA[<p>쿠팡 파트너스 API 테스트를 위해서 
회원가입 후 상품 링크 보기</p>
<p>아침대용으로 먹는 흰 앙꼬절편 
<img src="https://thumbnail7.coupangcdn.com/thumbnails/remote/492x492ex/image/retail/images/2020/10/14/18/8/79efe437-483c-45ea-9b56-79e4124c37bd.jpg" /></p>
<p><a href="https://coupa.ng/cbd3TC">https://coupa.ng/cbd3TC</a></p>
<p>이 링크를 통해 들어가서 물품을 구매하시면 
쿠팡 파트너스 활동으로 인정되어 수수료를 받을 수 있습니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[kakao 우편번호 API 연동]]></title>
            <link>https://velog.io/@django-support/react-modal-postcode-api</link>
            <guid>https://velog.io/@django-support/react-modal-postcode-api</guid>
            <pubDate>Wed, 10 Nov 2021 01:45:36 GMT</pubDate>
            <description><![CDATA[<h2 id="리액트-modal-이용한-주소검색-api-연동-만들기">리액트 Modal 이용한 주소검색 API 연동 만들기</h2>
<h3 id="결과물">결과물</h3>
<p><img src="https://images.velog.io/images/django-support/post/585333a5-b9ae-4899-93b1-67757120aa5e/%EC%A3%BC%EC%86%8C%EA%B2%80%EC%83%89-modal.png" alt=""></p>
<p><img src="https://images.velog.io/images/django-support/post/a81f47aa-f2fd-44ce-9df3-2e1de9f1996a/detail-%EC%A3%BC%EC%86%8C%EA%B2%80%EC%83%89.png" alt=""></p>
<h3 id="로직">로직</h3>
<ol>
<li>버튼 클릭</li>
<li>modal 띄우기</li>
<li>modal위에 카카오 우편검색 component 띄우기</li>
<li>주소 검색</li>
<li>상세 주소 입력 후 저장</li>
<li>전체 주소 보여주기</li>
</ol>
<h2 id="환경-세팅">환경 세팅</h2>
<p><code>yarn create react-app react-modal</code>
<code>cd react-modal</code>
<code>yarn add styled-components prop-types react-icons react-daum-postcode</code></p>
<h2 id="작업시작">작업시작</h2>
<ol>
<li>모달 만들기</li>
</ol>
<p><a href="https://medium.com/@bestseob93/%ED%9A%A8%EC%9C%A8%EC%A0%81%EC%9D%B8-%EB%A6%AC%EC%95%A1%ED%8A%B8-%EB%AA%A8%EB%8B%AC-react-modal-%EB%A7%8C%EB%93%A4%EA%B8%B0-bd003458e9d">https://medium.com/@bestseob93/%ED%9A%A8%EC%9C%A8%EC%A0%81%EC%9D%B8-%EB%A6%AC%EC%95%A1%ED%8A%B8-%EB%AA%A8%EB%8B%AC-react-modal-%EB%A7%8C%EB%93%A4%EA%B8%B0-bd003458e9d</a></p>
<p>참고하여 모달 만들어 주세요</p>
<ol start="2">
<li>버튼 클릭시 카카오 주소검색 띄우기</li>
</ol>
<pre><code class="language-javascript">import React, { useCallback, useState } from &quot;react&quot;;
import Modal from &quot;../components/Modal&quot;;
import DaumPostcode from &quot;react-daum-postcode&quot;;

function ModalPage() {
  const [modalVisible, setModalVisible] = useState(false);
  const [isOpenSecondPopup, setIsOpenSecondPopup] = useState(false);
  const [address, setAddress] = useState(null);
  const [postCodes, setPostCodes] = useState(null);
  const [detailAddress, setDetailAddress] = useState(&quot;&quot;);

  const openModal = useCallback(() =&gt; {
    setModalVisible(true);
  }, []);

  const closeModal = useCallback(() =&gt; {
    setModalVisible(false);
  }, []);

  const handleComplete = useCallback((data) =&gt; {
    let fullAddress = data.address;
    let extraAddress = &quot;&quot;;
    let zoneCodes = data.zonecode;
    if (data.addressType === &quot;R&quot;) {
      if (data.bname !== &quot;&quot;) {
        extraAddress += data.bname;
      }
      if (data.buildingName !== &quot;&quot;) {
        extraAddress +=
          extraAddress !== &quot;&quot; ? `, ${data.buildingName}` : data.buildingName;
      }
      fullAddress += extraAddress !== &quot;&quot; ? ` (${extraAddress})` : &quot;&quot;;
    }
    //fullAddress -&gt; 전체 주소반환
    setAddress(fullAddress);
    setPostCodes(zoneCodes);
    setIsOpenSecondPopup(true);
  }, []);

  return (
    &lt;&gt;
      &lt;h3 className=&quot;text&quot;&gt;배송지&lt;/h3&gt;
      {address ? (
        &lt;div&gt;
          &lt;div className=&quot;text&quot;&gt;주소 : {address}&lt;/div&gt;
          &lt;div className=&quot;text&quot;&gt;우편번호 : {postCodes}&lt;/div&gt;
        &lt;/div&gt;
      ) : (
        &lt;div className=&quot;text&quot;&gt;
          &lt;span className=&quot;emph&quot;&gt;배송지 입력을하고&lt;/span&gt; &lt;br /&gt;
          배송유형을 확인해 보세요!
        &lt;/div&gt;
      )}
      &lt;button onClick={openModal}&gt;Open Modal&lt;/button&gt;
      {modalVisible &amp;&amp; (
        &lt;Modal
          visible={modalVisible}
          closable={true}
          maskClosable={true}
          onClose={closeModal}
        &gt;
          &lt;DaumPostcode onComplete={handleComplete} className=&quot;post-code&quot; /&gt;
        &lt;/Modal&gt;
      )}
    &lt;/&gt;
  );
}
export default ModalPage;
</code></pre>
<p>*<em>openModal 과 closeModal 함수를 통해서 버튼 클릭시 Modal을 열고 닫을수 있게 한다.
*</em></p>
<pre><code class="language-javascript">{address ? (
        &lt;div&gt;
          &lt;div className=&quot;text&quot;&gt;주소 : {address}&lt;/div&gt;
          &lt;div className=&quot;text&quot;&gt;우편번호 : {postCodes}&lt;/div&gt;
        &lt;/div&gt;
      ) : (
        &lt;div className=&quot;text&quot;&gt;
          &lt;span className=&quot;emph&quot;&gt;배송지 입력을하고&lt;/span&gt; &lt;br /&gt;
          배송유형을 확인해 보세요!
        &lt;/div&gt;
 )}</code></pre>
<p>그리고 address 주소가 존재할 때는 주소와 우편변호를 보여주고 </p>
<p><img src="https://images.velog.io/images/django-support/post/83b1effd-4c0a-44ed-ac2a-83d21cac030a/result.png" alt=""></p>
<p>null일경우 배송지를 입력하라는 글을 보여줌 </p>
<p><img src="https://images.velog.io/images/django-support/post/7970e53f-6560-4cd7-b73a-9a9a73f7b095/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7,%202021-11-10%2012-49-32.png" alt=""></p>
<p><strong>버튼 클릭시, Modal 의 children 자리에 DaumPostcode component를 넣어 
Modal 위에 띄우도록 만들었다.</strong></p>
<pre><code class="language-javascript">

import React, { useCallback, useState } from &quot;react&quot;;
import Modal from &quot;../components/Modal&quot;;
import DaumPostcode from &quot;react-daum-postcode&quot;;

function ModalPage() {
(...)
  const handleComplete = useCallback((data) =&gt; {
    let fullAddress = data.address;
    let extraAddress = &quot;&quot;;
    let zoneCodes = data.zonecode;
    if (data.addressType === &quot;R&quot;) {
      if (data.bname !== &quot;&quot;) {
        extraAddress += data.bname;
      }
      if (data.buildingName !== &quot;&quot;) {
        extraAddress +=
          extraAddress !== &quot;&quot; ? `, ${data.buildingName}` : data.buildingName;
      }
      fullAddress += extraAddress !== &quot;&quot; ? ` (${extraAddress})` : &quot;&quot;;
    }
    //fullAddress -&gt; 전체 주소반환
    setAddress(fullAddress);
    setPostCodes(zoneCodes);
    setIsOpenSecondPopup(true);
  }, []);

  return (
    (...)
      &lt;button onClick={openModal}&gt;Open Modal&lt;/button&gt;
      {modalVisible &amp;&amp; (
        &lt;Modal
          visible={modalVisible}
          closable={true}
          maskClosable={true}
          onClose={closeModal}
        &gt;
          &lt;DaumPostcode onComplete={handleComplete} className=&quot;post-code&quot; /&gt;
        &lt;/Modal&gt;
      )}
    &lt;/&gt;
  );
}
export default ModalPage;</code></pre>
<ol start="3">
<li>상세 주소 입력<pre><code class="language-javascript">function ModalPage() {
const onChange = useCallback((e) =&gt; {
 setDetailAddress(e.target.value);
}, []);
/* 
   여기 부분 추가
   클릭시 Modal 창 닫기  &amp;&amp; 상세페이지 닫기
*/
const onClick = useCallback(
 (e) =&gt; {
   e.preventDefault();
   setAddress(address + detailAddress);
   setIsOpenSecondPopup(false);
   closeModal(false);
 },
 [closeModal, address, detailAddress, setAddress]
);
return (
   &lt;button onClick={openModal}&gt;Open Modal&lt;/button&gt;
   {modalVisible &amp;&amp; (
     &lt;Modal
       visible={modalVisible}
       closable={true}
       maskClosable={true}
       onClose={closeModal}
     &gt;
       &lt;DaumPostcode onComplete={handleComplete} className=&quot;post-code&quot; /&gt;
       /* 여기 부분 추가*/
       {isOpenSecondPopup &amp;&amp; (
         &lt;div&gt;
           &lt;h3&gt;상세 주소 입력&lt;/h3&gt;
           &lt;input
             placeholder=&quot;상세 주소를 입력해 주세요&quot;
             onChange={onChange}
             value={detailAddress}
           /&gt;
           &lt;button onClick={onClick}&gt;저장&lt;/button&gt;
         &lt;/div&gt;
       )}
     &lt;/Modal&gt;
   )}
 &lt;/&gt;
);
}
export default ModalPage;</code></pre>
</li>
</ol>
<p><strong>DaumPostcode component와 나란히 상세주소 페이지를 만들어 카카오 주소검색을 마친후 
상세페이지가 볼수 있도록 했다.</strong></p>
<h2 id="최종-결과물">최종 결과물</h2>
<h3 id="modalpagejs">ModalPage.js</h3>
<pre><code class="language-javascript">import React, { useCallback, useState } from &quot;react&quot;;
import Modal from &quot;../components/Modal&quot;;
import DaumPostcode from &quot;react-daum-postcode&quot;;
function ModalPage() {
  const [modalVisible, setModalVisible] = useState(false);
  const [isOpenSecondPopup, setIsOpenSecondPopup] = useState(false);
  const [address, setAddress] = useState(null);
  const [postCodes, setPostCodes] = useState(null);
  const [detailAddress, setDetailAddress] = useState(&quot;&quot;);

  const openModal = useCallback(() =&gt; {
    setModalVisible(true);
  }, []);
  const closeModal = useCallback(() =&gt; {
    setModalVisible(false);
  }, []);

  const onChange = useCallback((e) =&gt; {
    setDetailAddress(e.target.value);
  }, []);
  const handleComplete = useCallback((data) =&gt; {
    let fullAddress = data.address;
    let extraAddress = &quot;&quot;;
    let zoneCodes = data.zonecode;
    if (data.addressType === &quot;R&quot;) {
      if (data.bname !== &quot;&quot;) {
        extraAddress += data.bname;
      }
      if (data.buildingName !== &quot;&quot;) {
        extraAddress +=
          extraAddress !== &quot;&quot; ? `, ${data.buildingName}` : data.buildingName;
      }
      fullAddress += extraAddress !== &quot;&quot; ? ` (${extraAddress})` : &quot;&quot;;
    }
    //fullAddress -&gt; 전체 주소반환
    setAddress(fullAddress);
    setPostCodes(zoneCodes);
    setIsOpenSecondPopup(true);
  }, []);
  const onClick = useCallback(
    (e) =&gt; {
      e.preventDefault();
      setAddress(address + detailAddress);
      setIsOpenSecondPopup(false);
      closeModal(false);
    },
    [closeModal, address, detailAddress, setAddress]
  );
  return (
    &lt;&gt;
      &lt;h3 className=&quot;text&quot;&gt;배송지&lt;/h3&gt;
      {address ? (
        &lt;div&gt;
          &lt;div className=&quot;text&quot;&gt;주소 : {address }&lt;/div&gt;
          &lt;div className=&quot;text&quot;&gt;우편번호 : {postCodes}&lt;/div&gt;
        &lt;/div&gt;
      ) : (
        &lt;div className=&quot;text&quot;&gt;
          &lt;span className=&quot;emph&quot;&gt;배송지 입력을하고&lt;/span&gt; &lt;br /&gt;
          배송유형을 확인해 보세요!
        &lt;/div&gt;
      )}
      &lt;button onClick={openModal}&gt;Open Modal&lt;/button&gt;
      {modalVisible &amp;&amp; (
        &lt;Modal
          visible={modalVisible}
          closable={true}
          maskClosable={true}
          onClose={closeModal}
        &gt;
          &lt;DaumPostcode onComplete={handleComplete} className=&quot;post-code&quot; /&gt;
          {isOpenSecondPopup &amp;&amp; (
            &lt;div&gt;
              &lt;h3&gt;상세 주소 입력&lt;/h3&gt;
              &lt;input
                placeholder=&quot;상세 주소를 입력해 주세요&quot;
                onChange={onChange}
                value={detailAddress}
              /&gt;
              &lt;button onClick={onClick}&gt;저장&lt;/button&gt;
            &lt;/div&gt;
          )}
        &lt;/Modal&gt;
      )}
    &lt;/&gt;
  );
}
export default ModalPage;</code></pre>
<h3 id="componentsmodaljs">components/Modal.js</h3>
<pre><code class="language-javascript">
import React, { useEffect } from &quot;react&quot;;
import PropTypes from &quot;prop-types&quot;;
import styled from &quot;styled-components&quot;;
import { GrClose } from &quot;react-icons/gr&quot;;
import Portal from &quot;./Portal&quot;;

function Modal({
  className,
  onClose,
  maskClosable,
  closable,
  visible,
  children,
}) {
  const onMaskClick = (e) =&gt; {
    if (e.target === e.currentTarget) {
      onClose(e);
    }
  };

  const close = (e) =&gt; {
    if (onClose) {
      onClose(e);
    }
  };
  useEffect(() =&gt; {
    document.body.style.cssText = `position: fixed; top: -${window.scrollY}px`;
    return () =&gt; {
      const scrollY = document.body.style.top;
      document.body.style.cssText = `position: &quot;&quot;; top: &quot;&quot;;`;
      window.scrollTo(0, parseInt(scrollY || &quot;0&quot;) * -1);
    };
  }, []);
  return (
    &lt;Portal elementId=&quot;modal-root&quot;&gt;
      &lt;ModalOverlay visible={visible} /&gt;
      &lt;ModalWrapper
        className={className}
        onClick={maskClosable ? onMaskClick : null}
        tabIndex=&quot;-1&quot;
        visible={visible}
      &gt;
        &lt;ModalInner tabIndex=&quot;0&quot; className=&quot;modal-inner&quot;&gt;
          &lt;div className=&quot;close-btn&quot;&gt;
            {closable &amp;&amp; &lt;GrClose className=&quot;modal-close&quot; onClick={close} /&gt;}
          &lt;/div&gt;
          &lt;br /&gt;
          {children}
        &lt;/ModalInner&gt;
      &lt;/ModalWrapper&gt;
    &lt;/Portal&gt;
  );
}
Modal.propTypes = {
  visible: PropTypes.bool,
};

Modal.defaultProps = {
  closable: true,
  maskClosable: true,
  visible: false,
};
const ModalWrapper = styled.div`
  box-sizing: border-box;
  display: ${(props) =&gt; (props.visible ? &quot;block&quot; : &quot;none&quot;)};
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: 1000;
  overflow: auto;
  outline: 0;
`;

const ModalOverlay = styled.div`
  box-sizing: border-box;
  display: ${(props) =&gt; (props.visible ? &quot;block&quot; : &quot;none&quot;)};
  position: fixed;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  background-color: rgba(0, 0, 0, 0.6);
  z-index: 999;
`;

const ModalInner = styled.div`
  box-sizing: border-box;
  position: relative;
  box-shadow: 0 0 6px 0 rgba(0, 0, 0, 0.5);
  background-color: #fff;
  border-radius: 10px;
  width: 360px;
  max-width: 480px;
  top: 50%;
  transform: translateY(-50%);
  margin: 0 auto;
  padding: 40px 20px;
  .close-btn {
    float: right;
  }
`;

export default Modal;</code></pre>
<h3 id="componentsportaljs">components/Portal.js</h3>
<pre><code class="language-javascript">import React, { useMemo } from &quot;react&quot;;
import { createPortal } from &quot;react-dom&quot;;

function Portal({ children, elementId }) {
  const rootElement = useMemo(
    () =&gt; document.getElementById(elementId),
    [elementId]
  );
  return createPortal(children, rootElement);
}
export default Portal;</code></pre>
<h3 id="appjs">App.js</h3>
<pre><code class="language-javascript">import React from &quot;react&quot;;
import ModalPage from &quot;./pages/ModalPage&quot;;
function App() {
  return (
    &lt;div className=&quot;App&quot;&gt;
      &lt;ModalPage /&gt;
    &lt;/div&gt;
  );
}

export default App;</code></pre>
<p><a href="https://coupa.ng/cbd3TC"><img src="https://thumbnail8.coupangcdn.com/thumbnails/remote/492x492ex/image/retail/images/2020/10/14/18/2/66f76b58-b736-46a2-9202-f234f773a986.jpg" width="30%" height="30%"></a></p>
<p>이 포스팅은 쿠팡 파트너스 활동의 일환으로 이에 따른 일정액의 수수료를 제공받을 수 있습니다.</p>
<p>출처: <a href="https://medium.com/@bestseob93/%ED%9A%A8%EC%9C%A8%EC%A0%81%EC%9D%B8-%EB%A6%AC%EC%95%A1%ED%8A%B8-%EB%AA%A8%EB%8B%AC-react-modal-%EB%A7%8C%EB%93%A4%EA%B8%B0-bd003458e9d">https://medium.com/@bestseob93/%ED%9A%A8%EC%9C%A8%EC%A0%81%EC%9D%B8-%EB%A6%AC%EC%95%A1%ED%8A%B8-%EB%AA%A8%EB%8B%AC-react-modal-%EB%A7%8C%EB%93%A4%EA%B8%B0-bd003458e9d</a>
<a href="https://velog.io/@nangman/%EC%A3%BC%EC%86%8C-API%ED%99%9C%EC%9A%A9-KAKAO">https://velog.io/@nangman/%EC%A3%BC%EC%86%8C-API%ED%99%9C%EC%9A%A9-KAKAO</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[2.2.4 컨테이너를 외부에 노출]]></title>
            <link>https://velog.io/@django-support/2.2.4-%EC%BB%A8%ED%85%8C%EC%9D%B4%EB%84%88%EB%A5%BC-%EC%99%B8%EB%B6%80%EC%97%90-%EB%85%B8%EC%B6%9C</link>
            <guid>https://velog.io/@django-support/2.2.4-%EC%BB%A8%ED%85%8C%EC%9D%B4%EB%84%88%EB%A5%BC-%EC%99%B8%EB%B6%80%EC%97%90-%EB%85%B8%EC%B6%9C</guid>
            <pubDate>Thu, 10 Jun 2021 03:42:20 GMT</pubDate>
            <description><![CDATA[<h1 id="컨테이너를-외부에-노출">컨테이너를 외부에 노출</h1>
<ul>
<li>컨테이너는 가상 머신과 마찬가지로 가상 IP 주소를 할당 받습니다.</li>
<li>기본적으로 도커는 컨테이너에 172.17.0.x의 IP를 순차적으로 할당합니다.</li>
</ul>
<p>컨테이너 안에서 ifconfig 명령어로 컨테이너의 네트워크 인터페이스 확인!</p>
<p>만약 error 
<code>bash ifconfig command not found</code>
발견된다면 </p>
<p>google에 &quot;bash ifconfig command not found ubuntu docker&quot; 
검색 해서 해결 하시면 될 것입니다.!</p>
<p><code>apt-get update</code>
<code>apt-get install net-tools</code></p>
<p><img src="https://images.velog.io/images/django-support/post/73309384-d0a3-4aff-8b4c-b37dbb60d81a/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7,%202021-06-10%2010-48-08.png" alt=""></p>
<p>도커의 NAT IP인 172.17.0.2 할당 받은 eth0
로컬 호스트인 lo 인터페이스</p>
<p>외부에 컨테이너 안에 애플리케이션을 노출하기 위해서 eth0의 IP와 포트를
호스트의 IP와 포트에 바인딩해야 한다</p>
<p><code>sudo docker run -i -t --name mywebserver -p 80:80 ubuntu:18.04</code></p>
<p>호스트의 80번 포트와 컨테이너의 80번 포트를 연결하는 명령어!</p>
<p>여러개의 포트를 개방하려면 </p>
<p><code>sudo docker run -i -t -p 3306:3306 -p 192.168.0.100:7777:80 ubuntu:18.04</code></p>
<h2 id="에러">에러....</h2>
<pre><code>Status: Downloaded newer image for ubuntu:18.04
docker: Error response from daemon: driver failed programming external connectivity on endpoint crazy_mirzakhani (913508586d6c398eb11ee665e19d89cb1f51c412ba5e2cb4e5fb5cbdf00225dd): Error starting userland proxy: listen tcp4 192.168.0.100:7777: bind: cannot assign requested address.
ERRO[0006] error waiting for container: context canceled</code></pre><p>참조 </p>
<p><a href="https://stackoverflow.com/questions/42870005/how-to-install-ifconfig-command-in-my-ubuntu-docker-image">https://stackoverflow.com/questions/42870005/how-to-install-ifconfig-command-in-my-ubuntu-docker-image</a></p>
<p><a href="https://www.aladin.co.kr/shop/wproduct.aspx?ItemId=106596706">https://www.aladin.co.kr/shop/wproduct.aspx?ItemId=106596706</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[how to install docker]]></title>
            <link>https://velog.io/@django-support/how-to-install-docker</link>
            <guid>https://velog.io/@django-support/how-to-install-docker</guid>
            <pubDate>Fri, 28 May 2021 01:42:31 GMT</pubDate>
            <description><![CDATA[<h1 id="ubuntu-2004">ubuntu 20.04</h1>
<h4 id="apt-or-apt-get-업데이트">APT or APT-GET 업데이트</h4>
<p><code>sudo apt update</code>
or
<code>sudo apt-get update</code></p>
<h3 id="apt-업그레이드">APT 업그레이드</h3>
<p><code>sudo apt upgrade</code></p>
<h3 id="docker-다운로드">docker 다운로드</h3>
<p><code>sudo apt  install docker.io</code>
    or 
<code>sudo apt-get install docker.io</code></p>
<h3 id="docker-version-확인">docker version 확인</h3>
<p><code>sudo docker version</code></p>
<p>도커 버전확인 했다면 설치 완료!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[ec2 서버 다운 issue]]></title>
            <link>https://velog.io/@django-support/ec2-%EC%84%9C%EB%B2%84-%EB%8B%A4%EC%9A%B4-issue</link>
            <guid>https://velog.io/@django-support/ec2-%EC%84%9C%EB%B2%84-%EB%8B%A4%EC%9A%B4-issue</guid>
            <pubDate>Thu, 20 May 2021 03:12:14 GMT</pubDate>
            <description><![CDATA[<h3 id="ec2-데이터-부족으로-서버-다운-issue">ec2 데이터 부족으로 서버 다운 issue</h3>
<p>아무래도 crontab 돌리면서 log를 쌓으면서 생긴 문제가 
데이터 부족 경보를 뜨게 한거 같다.</p>
<p>다시 ec2재부팅하고 복구해서 문제를 한번 파악 해보고 싶었지만...
돈도 부족... 
시간이 실시간성으로 급한건 아니지만 개발진행을 늦추지 않기위해서 
새로 서버를 세팅했다. </p>
<p>분명히 이런일이 또 발생할 일이지만....
이런 일을 방지 하기 위해서 </p>
<ul>
<li>클라우드 와치 </li>
<li>스케일링 연결</li>
</ul>
<p>공부해서 문제를 방지 해봐야 겠다!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[styled-components error ]]></title>
            <link>https://velog.io/@django-support/styled-components-error</link>
            <guid>https://velog.io/@django-support/styled-components-error</guid>
            <pubDate>Tue, 04 May 2021 07:50:05 GMT</pubDate>
            <description><![CDATA[<pre><code class="language-javascript">import styled from &#39;styled-components;</code></pre>
<p>이 부분에서 </p>
<pre><code class="language-javascript">could not find a declaration file for module.... 뭐라고</code></pre>
<p>노랑색이 발생</p>
<p>npm i --save-dev @types/styled-components</p>
<p>입력하라고 하는데 ...
나는 npm 명령어가 없었다.</p>
<p>yarn 을 사용하고 있었다</p>
<p>아무리 찾아봐도 없길래 </p>
<p><code>yarn add @types/styled-components</code></p>
<p>명령어를 실행해서 다운받아보니 해결됨<del>~</del>^^</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[how to install zsh on ubuntu]]></title>
            <link>https://velog.io/@django-support/zsh-install</link>
            <guid>https://velog.io/@django-support/zsh-install</guid>
            <pubDate>Mon, 15 Mar 2021 00:57:45 GMT</pubDate>
            <description><![CDATA[<ol>
<li><p>zsh apt 설치
<code>apt-get install -y zsh</code></p>
</li>
<li><p>설치
<code>wget https://github.com/robbyrussell/oh-my-zsh/raw/master/tools/install.sh -O - | zsh || true</code></p>
</li>
<li><p>이건 뭔지 모르겠다. 
<code>chsh -s /usr/bin/zsh</code></p>
</li>
</ol>
<ol start="4">
<li>환경변수 설정
<code>~/.zshrc</code></li>
</ol>
<p><code>echo &#39;export PATH=&quot;/root/.pyenv/bin:$PATH&quot;&#39; &gt;&gt; ~/.zshrc</code></p>
<pre><code class="language-shell"># /home/$root계정이름/.pyenv/bin:$PAHT 설정해줘야함
export PATH=&quot;/home/lumen-dooh/.pyenv/bin:$PATH&quot;
eval &quot;$(pyenv init -)&quot;
eval &quot;$(pyenv virtualenv-init -)&quot;</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[drf ]]></title>
            <link>https://velog.io/@django-support/drf</link>
            <guid>https://velog.io/@django-support/drf</guid>
            <pubDate>Thu, 11 Mar 2021 09:03:32 GMT</pubDate>
            <description><![CDATA[<p>유저 : 정산정보
1 : 1 관계</p>
<p>정산 정보 : 정산 계좌
1 : 다 관계</p>
<p><code>models.py</code></p>
<pre><code class="language-python">
class 정산정보 모델(models.Model):
    user = models.OneToOne(User, on_delete=models.CACADE ...)
    email = models.EmailField()


class 정산계좌 모델(models.Model):
    정산정보 = models.ForeignKey(정산정보모델, on_delete=models.CACADE ...)
    account_number = models.CharField(&#39;계좌번호&#39;, ...)</code></pre>
<p><code>serializers.py</code></p>
<pre><code class="language-python">class 정산정보CreateSerializer:
    정산 계좌 = 정산계좌CreateSerializer(many=True, required=False)
       class Meta:
    model = 정산계좌
    fields = (  ... )

    @transaction.atomic()
    def create(self, validated_data):
        # 각자 모델에 필요한 데이터끼리 깔끔하게 정리하자!!!!!!!
        정산계좌_data = validated_data.pop(&#39;정산계좌_data&#39;)


        # 생성!!!!!!!!
        # get_or_create 로 다시 만들기를 하였을 때 버그가 안나게 할 수 있지만
        # 일부러 업데이트 방향으로 이끌기 위해 버그를 만들어 주었다.
        정산정보_instance = 정산정보모델.objects.create(
            ...
        )

        if 정산계좌_data:
            for 계좌정보 in 정산계좌_data:
                정산계좌모델.objects.create( ... )

        # 출력!!!!!
        return 정산정보_instance
</code></pre>
<p><code>views.py</code></p>
<pre><code class="language-python">
class 정산정보APIView(generics.ListCreateAPIView):
        if self.request.method == &#39;GET&#39;:
            return 정산정보serializer
        elif self.request.method == &#39;POST&#39;:
            return 정산정보CreateSerializer
</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[poetry 제거]]></title>
            <link>https://velog.io/@django-support/poetry-uninstall</link>
            <guid>https://velog.io/@django-support/poetry-uninstall</guid>
            <pubDate>Wed, 10 Mar 2021 13:37:41 GMT</pubDate>
            <description><![CDATA[<h1 id="1-get-poetrypy-download">1. get-poetry.py download</h1>
<p><a href="https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py">https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py</a></p>
<p>여기 링크 들어가서 get-poetry.py 파일을 만드세요!</p>
<h1 id="2-command-입력">2. command 입력</h1>
<p><code>python get-poetry.py --uninstall</code></p>
<p>커맨드에 입력하면 poetry 제거가 완료 됩니다.</p>
<p>그리고</p>
<p>다시 재설치 하시면 되요</p>
<p><code>curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | python -</code></p>
<p>poetry --self update 하다가</p>
<p>error </p>
<pre><code>Looking in links: /tmp/tmpfyhkwsq7
Requirement already satisfied: setuptools in /home/kimdooh/.pyenv/versions/3.7.5/envs/volvo-env/lib/python3.7/site-packages (41.2.0)
Requirement already satisfied: pip in /home/kimdooh/.pyenv/versions/3.7.5/envs/volvo-env/lib/python3.7/site-packages (19.2.3)</code></pre><p>에러나면 다시 지우고 다시 설치 하는게 좋은것 같아요</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[vscode에서 한글이 타이핑 안됨 ]]></title>
            <link>https://velog.io/@django-support/vscode-not-work-hangul</link>
            <guid>https://velog.io/@django-support/vscode-not-work-hangul</guid>
            <pubDate>Thu, 28 Jan 2021 03:47:48 GMT</pubDate>
            <description><![CDATA[<h1 id="vscode에서-한글이-안되는-경우-on-ubuntu-2004">vscode에서 한글이 안되는 경우 on ubuntu 20.04</h1>
<p>출처 : <a href="https://superuser.com/questions/1113022/how-do-i-remove-vs-code-settings-from-ubuntu">https://superuser.com/questions/1113022/how-do-i-remove-vs-code-settings-from-ubuntu</a></p>
<p>Try renaming ~/.config/Code/User/settings.json.</p>
<p>Or just move/delete the folders ~/.config/Code and ~/.vscode.</p>
<p>You may want to backup any code snippets in ~/.config/Code/User/snippets/</p>
<p>See also: Visual Studio Code User and Workspace Settings</p>
<p>나같은경우에는 Code 파일을 지움</p>
<p>그리고 </p>
<p>snap 으로 설치한 경우,</p>
<p><code>sudo snap install code</code>
or 
<code>sudo snap install code --classic</code></p>
<p>이런식으로 지워주면 될것 같다.</p>
<p>If you installed via Snap:</p>
<p><code>$sudo snap remove vscode</code></p>
<p>If you installed via apt:</p>
<p><code>$sudo apt-get purge code</code></p>
<p>출처 : <a href="https://gist.github.com/philoskim/a79440bd51ae40f04a4d7cafa472caf1">https://gist.github.com/philoskim/a79440bd51ae40f04a4d7cafa472caf1</a>
다 지웠으면 </p>
<p>다음 싸이트에서 .deb 형식의 Visual Studio Code를 직접 다운로드 받는다.</p>
<p><a href="https://code.visualstudio.com/download">https://code.visualstudio.com/download</a></p>
<p>내려받은 후, 그대로 설치 하지말고!!!!!!
자기가 다운로드 받은 위치 찾아!!!! 그리고</p>
<p><code>$ sudo dpkg -i ~/다운로드/code_1.40.2-1574694120_amd64.deb</code></p>
<p>이 명령어를 통해서 설치를 해줘</p>
<p>난 여기서 성공했음.</p>
<hr>
<p>설치 중에 의존 라이브러리가 없다는 메시지가 나오면, 다음을 한번 더 실행해 준다.</p>
<p>$ sudo apt -f install</p>
<p>이상 한글 타이핑 안되는 문제 해결</p>
]]></description>
        </item>
    </channel>
</rss>