K-디지털트레이닝(빅데이터) 10일차

유현민·2021년 8월 6일
0

(정리완료)
오늘도 어제와 마찬가지로 한번 더 다른 기능을 만들었다.

  1. 장고 설치
pip install django

django-admin startproject config .

python manage.py migrate(default값으로 데이터베이스 만든다)

python manage.py createsuperuser(관리자 계정)

python manage.py startapp photo
  1. settings.py
'photo',
  1. models.py
from django.contrib.auth.models import User#작성자 가져옴(기본설정 되어있는 user를 가져온다)


class Photo(models.Model):#model 받아옴
    author = models.ForeignKey(User, on_delete=models.CASCADE, related_name='user_photos')#user로 연결하고 삭제되면 같이 삭제되게 한다
    photo = models.ImageField(upload_to='photos/%Y/%m/%d', default='photos/no_img.png')#디렉토리 찾는 창을 띄워주는 형식이다.포토 폴더안에 연도/월/날짜 를 만들어준다.
    #없으면 no_img.png를 만들어줘서 오류를 방지해준다.
    text = models.TextField()#본문 적기

    created = models.DateTimeField(auto_now_add=True)#생성된 날짜, 자동으로 현재시간을 추가해준다.
    updated = models.DateTimeField(auto_now=True)#수정된 시간을 넣어준다.



    class Meta:
        ordering = ['-updated'] #업데이트된 시각을 기준으로 정렬한다.(-는 내림차순 없으면 오름차순)


    def __str__(self):
        return self.author.username + " " + self.created.strftime("%Y-%m-%d")#users안에 username이 있다.
    #이름과 시간을 받아온다. 시 분 초가 대문자를 쓰고 나머지는 소문자로 쓴다
######################만들거라고 정의만 한거다.
pip install pillow(사진 저장하려면 설치해야한다)
python manage.py makemigrations photo(만든다)
python manage.py migrate photo(적용하기)
  1. admin.py
from django.contrib import admin
from .models import * #같은 폴더에 있으면 .만 붙이면된다. 아니면 경로 써줘야함... *은 전체다 불러옴
# Register your models here.

admin.site.register(Photo)#admin에 photo의 데이터를 등록해줬다.
  1. settings.py
import os

MEDIA_URL = '/media/'

MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
베이스 디렉터리를 설정해서 경로를 지정해준다.
  1. admin.py
admin.site.register(Photo, PhotoAdmin)#admin에 photo의 데이터를 등록해줬다.///만든걸 적용해야한다.

class PhotoAdmin(admin.ModelAdmin):
    list_display = ['id', 'author', 'created', 'updated']#리스트를 어떻게 표현할것인가
    raw_id_fields = ['author']#기준 id
    list_filter = ['created', 'updated', 'author']#단어들이 떠서 검색하기 편함(필터로 쓸 값들)
    search_fields = ['text', 'created'] #본문과 생성일 기준으로 검색
    ordering = ['-updated', '-created'] #정렬기준은 -(내림차순) 업데이트날짜와 생성 날짜
  1. views.py

from django.shortcuts import render, redirect  # 다시 주소 돌려주는거 호출
from django.views.generic.edit import CreateView, DeleteView, UpdateView  # 기능 호출
from .models import Photo


class PhotoUploadView(CreateView):  # 생성되는 페이지를 직접 작성하지 않고 장고에서 생성된거로 쓴다
    model = Photo
    field = ['photo', 'text']  # 입력은 포토와 텍스트를 가져온다
    template_name = 'photo/upload.html'  # 여기랑 연결시킨다

    def form_valid(self, form):
        form.instance.author_id = self.request.user.id  # 현재 열려있는 유저 아이디랑 연결시킨다
        if form.is_valid():  # 입력없을때 액션하면 오류막아줌
            form.instance.save()  # 값이 있으면 save
            return redirect('/')
        else:
            return self.render_to_response({'form': form})  # 값이없으면 여기로보낸다

class PhotoDeleteView(DeleteView)
    model = Photo
    success_url = '/' #성공하면 리스트페이지로 넘긴다
    template_name = 'photo/delete.html'


class PhotoUpdateView(UpdateView):#수정
    model = Photo
    field = ['photo', 'text'] #수정 필드
    template_name = 'photo/update.html'

def photo_list(request):  # 리스트 페이지를 보여주기 위한... 데이터를 html로 통채로 넘겨주고 html에서 처리하게한다.
    photos = Photo.objects.all()  # 데이터를 전부 photos에 담겠다
    return render(request, 'photo/list.html',
                  {'photos': photos})  # photoslist req 되면 (photo/list.html 주소일때) {'photos:photos}를 불러온다.
  1. photo/urls.py
from django.urls import path
from django.views.generic.detail import DetailView

from .models import Photo  # 데이터 불러옴
from .views import *  # 다불러옴

app_name = 'photo'

urlpatterns = [
    path('', photo_list, name='photo_list'),  # 없으면 photo_list 호출
    path('detail/<int:pk>', DetailView.as_view(model=Photo, template_name='photo/detail.html'), name='photo_detail'),
    # 안만들고 바로씀, 그대신 형식 적어줘야함
    path('upload/', PhotoUploadView.as_view(), name='photo_upload'),  # view에서 정의한거 그대로씀
    path('delete/<int:pk>', PhotoDeleteView.as_view(), name='photo_delete'),
    path('update/<int:pk>', UpdateView.as_view(), name='photo_update'),

]
  1. config/urls.py
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('photo.urls'))  # 바로들어가짐, photo.urls로 길 안내를 해준다.
]
  1. templates 폴더 만들어준다
  • 안에 base.html 만들어준다.
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{% block title %}{% endblock %}</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.0/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-KyZXEAg3QhqLMpG8r+8fhAXLRk2vvoC2f3B09zVXn8CA5QIVfZOJ3BCsw2P0p/We" crossorigin="anonymous">

</head>
<body>
    <nav class="navbar navbar-expand-lg navbar-light bg-light">
      <div class="container">
        <a class="navbar-brand" href="">Photo</a>
        <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
          <span class="navbar-toggler-icon"></span>
        </button>
        <div class="collapse navbar-collapse" id="navbarNav">
          <ul class="navbar-nav">
            <li class="nav-item">



              <a class="nav-link" aria-current="page" href="/">Home</a>
            </li>


              {% if user.is_authenticated %}
              <li class="nav-item">
              <a class="nav-link" aria-current="page" href="">Welcome {{ user.get_username }}</a>
              </li>

              <li class="nav-item">
              <a class="nav-link" aria-current="page" href="{% url 'photo:photo_upload %}">Upload</a>
              </li>

              <li class="nav-item">
              <a class="nav-link" aria-current="page" href="">Logout</a>
              </li>


              {% else %}
              <li class="nav-item">
              <a class="nav-link" aria-current="page" href="">Login</a>
            </li>

              <li class="nav-item">
              <a class="nav-link active" aria-current="page" href="">SignUp</a>
            </li>
              {% endif %}

          </ul>
        </div>
      </div>
    </nav>
    <div class="container mt-5">
        {% block content %}

        {% endblock %}
    </div>
    <footer class="container-fluid footer">
        <p>&copy; 2021 Bigdata. Powered by YOO</p>

    </footer>

    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.0/dist/js/bootstrap.bundle.min.js" integrity="sha384-U1DAWAznBHeqEIlVSCgzq+c9gqGAJn5c/t99JyeKa9xxaYpSvHU5awsuZVVFIhvj" crossorigin="anonymous"></script>

</body>
</html>
  1. settings.py
'DIRS': [os.path.join(BASE_DIR,"templates")], 추가
  1. base.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>GasanGram {% block title %}{% endblock %}</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.0/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-KyZXEAg3QhqLMpG8r+8fhAXLRk2vvoC2f3B09zVXn8CA5QIVfZOJ3BCsw2P0p/We" crossorigin="anonymous">

</head>
<body>
    <nav class="navbar navbar-expand-lg navbar-light bg-light">
      <div class="container">
        <a class="navbar-brand" href="/">Gram</a>
        <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
          <span class="navbar-toggler-icon"></span>
        </button>
        <div class="collapse navbar-collapse" id="navbarNav">
          <ul class="navbar-nav">
            <li class="nav-item">
              <a class="nav-link" aria-current="page" href="/">Home</a>
            </li>
            {% if user.is_authenticated %}
            <li class="nav-item">
              <a class="nav-link" aria-current="page" href="">Welcome {{ user.get_username }}</a>
            </li>
            <li class="nav-item">
              <a class="nav-link" aria-current="page" href="{% url 'photo:photo_upload' %}">Upload</a>
            </li>
            <li class="nav-item">
              <a class="nav-link" aria-current="page" href="">Logout</a>
            </li>
            {% else %}
            <li class="nav-item">
              <a class="nav-link" aria-current="page" href="">Login</a>
            </li>
            <li class="nav-item">
              <a class="nav-link" aria-current="page" href="">SignUp</a>
            </li>
            {% endif %}
          </ul>
        </div>
      </div>
    </nav>
    <div class="container mt-5">
        {% block content %}

        {% endblock %}
    </div>
    <footer class="container-fluid footer">
        <p>&copy; 2021 GasanBigdata. Powered By UnionGraphix</p>
    </footer>

    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.0/dist/js/bootstrap.bundle.min.js" integrity="sha384-U1DAWAznBHeqEIlVSCgzq+c9gqGAJn5c/t99JyeKa9xxaYpSvHU5awsuZVVFIhvj" crossorigin="anonymous"></script>

</body>
</html>
  1. list.html 수정
{% extends 'base.html' %}

{% block title %}
- List
{% endblock %}

{% block content %}
    {% for post in photos %}
        <div class="row">
            <div class="col-12 panel panel-default">
                <div><img src="{{ post.photo.url }}" style="width:100%;"></div>
                <p>{{ post.author.username }}</p>
                <p>{{ post.text | linebreaksbr }}</p>
                <div class="text-right">
                    <a href="{% url 'photo:photo_detail' pk=post.id %}" class="btn btn-xs btn-success">reply</a>
                </div>
            </div>
        </div>
    {% endfor %}
{% endblock %}
  1. config/urls.py(사진 불러오기)
from django.contrib import admin
from django.urls import path, include

from django.conf.urls.static import static #고정파일 불러오기
from django.conf import settings



urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('photo.urls'))  # 바로들어가짐, photo.urls로 길 안내를 해준다.
]


urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)#static에 관련된것만 붙여줘!
  1. base.html(viewport 추가)
<meta name="viewport" content="width=device-width, initial-scale=1">
  1. detail.html
{% extends 'base.html' %}

{% block title %}
    {{ object.text | truncatechars:10}}<!-- 10글자만 나오게 만듦-->
{% endblock %}

{% block content %}
<div class="row my-3">
    <div class="col-12 panel panel-default">
        <div><img src="{{ object.photo.url }}" style="width:100%;"></div>
        <p>{{ object.author.username }}</p>
        <p>{{ object.text | linebreaksbr }}</p>
        <a href="{% url 'photo:photo_delete' pk=object.id %}"class="btn btn-outline-danger btn-sm float-right">Delete</a>
        <a href="{% url 'photo:photo_update' pk=object.id %}"class="btn btn-outline-success btn-sm float-right">Modify</a>

        </div>

    </div>
</div>
{% endblock %}
  1. delete.html
{% extends 'base.html' %}

{% block title %}
    - Delete
{% endblock %}

{% block content %}
<div class="row my-5">
    <div class="col-12 panel panel-default">
        <div class="alert alert-info">
            정말로 {{ object }}을 삭제 하실건가요?
        </div>
        <form action="" method="post">
            {% csrf_token %}
            {{ form.as_p }}
            <input type="submit" class="btn btn-danger" value="Confirm">
        </form>
    </div>
</div>
{% endblock %}
  1. model.py
from django.urls import reverse

    def get_absolute_url(self):
        return reverse('photo:photo_detail', args=[str(self.id)])
#다시넘겨준다
  1. update.html
{% extends 'base.html' %}

{% block title %}
    {{ object.text | truncatechars:10 }} - update
{% endblock %}

{% block content %}
<div class="row my-5">
     <div class="row">
        <div class="col-12 panel panel-default">
            <form action="" method="post">
                {% csrf_token %}
                {{ form.as_p }}
                <input type="submit" class="btn btn-primary" value="Update">
            </form>
        </div>
    </div>
</div>
{% endblock %}
  1. 로그인 만들기
python manage.py startapp accounts

config/settings.py

accounts추가해주기

accounts/urls.py 추가


from django.urls import path
from django.contrib.auth import views as auth_view


urlpatterns = [
    path('login/', auth_view.LoginView.as_view(), name='login'),
    path('logout/', auth_view.LogoutView.as_view(template_name='registration/logout.html'), name='logout'),
]
  1. config.urls.py
path('accounts/', include('accounts.urls')),
  1. login.html 만들기
{% extends 'base.html' %}

{% block title %}
    - Login
{% endblock %}

{% block content %}
<div class="row my-5">
     <div class="row">
        <div class="col-12 panel panel-default">
        <div class="alert alert-info">
            로그인
        </div>
            <form action="" method="post">
                {% csrf_token %}
                {{ form.as_p }}
                <input type="submit" class="btn btn-primary" value="Login">
            </form>
        </div>
    </div>
</div>
{% endblock %}
  1. logout.html 만들기
{% extends 'base.html' %}

{% block title %}
    - Logout
{% endblock %}

{% block content %}
<div class="row my-5">
    <div class="col-12 panel panel-default">
        <div class="alert alert-info my-4">
            로그아웃 되었습니다.
        </div>
        <a class="btn btn-primary" href="{% url 'login' %}">Click to Login</a>
    </div>
</div>
{% endblock %}
  1. base.html 고치기
              <a class="nav-link" aria-current="page" href="{% url 'logout' %}">Logout</a>
            </li>
            {% else %}
            <li class="nav-item">
              <a class="nav-link" aria-current="page" href="{% url 'login' %}">Login</a>
  1. settings.py
    맨 밑에
    LOGIN_REDIRECT_URL = '/'
    추가하기

profile
smilegate megaport infra

0개의 댓글