Static 정적 파일
원본 그대로 보여주는 파일
요청한 것을 그대로 응답하는 되는 파일
기본 경로 > app_name/static
{% load static %}
<img src = "{%static ''%}"
실제 배포 환경에서 필요합니다.
The Staticfiles app
STATIC_URL
- static_root에 있는 정적 파일을 참조 할 때 사용할 URL
- 실제 파일이나 디렉토리가 아니며, URL로만 존재
실습하기
이 오류가 발생하게된다. 왼쪽에 보면 requirements 를보고 설치를하여라.
가상환경을 만들어 설치하자
source venv/Scripts/activate
으로 가상 환경을 활성화 시켜주자. 그리고 만약 왼쪽아래에 "Select python ..."이 뜬다면 클릭해서 ('venv')가 붙은녀석을 클릭해주자.
다음 리콰이먼트를 이용하여 설치하자
pip install -r requements.txt
tip = 중간까지 단어를치다 tap 을 눌러주면 자동완성
설치가 완료됐다. 한번 서버를 다시 실행시켜보자.
정상 실행이 된다!
하지만 사이트에 들어가보면?
http://127.0.0.1:8000/articles/index
오류가 뜬다.
아래로 내려보면 테이블이 검색이안된다고 뜬다. 즉, migrate 시켜줘야한다!
python manage.py migrate
후에 다시 서버를 실행시켜보자
하지만 이렇게하면 실제 데이터는 없다 ㅠㅠ 만약 실제 데이터가 있다면! 우리는 덤프 데이터를 하여야한다.
STATIC FILE 배워보자
개발자 길을 걸을땐 검색을 생활하합시다..
django 를 검색해봅시다. "django static files"
정적 파일을 구성하는 중입니다.¶
- 《django.contrib.static files》가 다음 설정에 포함되도록 하십시오.
INSTALLED_APPS
. - 설정 파일에서 다음을 정의합니다.:setting:STATIC_URL, 예를 들어:
STATIC_URL = '/static/'
- 템플릿에서 :ttag:〉static〉 템플릿 태그를 사용하여 구성된 를 사용하여 지정된:setting:STATICFILES_STORAGE.에 대한 URL을 빌드합니다.
{% load static %} <img src="{% static 'my_app/example.jpg' %}" alt="My image">
- 정적 파일을 앱의 《static》 폴더에 저장합니다. 예를 들어 다음과 같습니다.
my_app/static/my_app/example.jpg
.
우리는 위의 내용을 검토해보자
- crud > settings.py 에 설정돼있다.
- URL 또한 포함돼있다.
- URL도 빌드돼있다
특정 앱에서만 쓰지않는 파일이있을 텐데 우린 아래를 읽어보자.
프로젝트에 특정 앱에 연결되지 않은 정적 자산도 있을 수 있습니다. 앱 내에서 《static/》 디렉토리를 사용하는 것 외에도 디렉토리 목록(:seting:》)을 정의할 수 있습니다.Django가 정적 파일도 찾을 수 있는 설정 파일의 STATICFILES_DIRS)입니다. 예를 들어 다음과 같습니다.
STATICFILES_DIRS = [
BASE_DIR / "static",
'/var/www/static/',
]
이 부분이다.
개발하는 부분에서는 장고가 자동으로 수행해준다. 하지만 이 방법들은 비효율적이다. 실제로는 우리가 다른 방식으로 사용하자
STATIC 폴더만들기
안에 또 articles 를 만들어주고
css, javascript.jpg 를 저장하는 공간이된다.
이제 보여주자
templates > index.html 로가자
다음 load staitc을 적어주고 img 태그를 적어주자
이미지는 이제 서버 껏다켜줍시다.
늠름한.. 이재용님....
그리고 개발자 도구 > network 탭을 누르고 all로 바꿔보자
그럼 장고 서버로부터 받은 모든 것들을 볼수있다.
여기서 마우스를 가져다되면 url이 뜬다.
저부분을 담당하는 부분이 바로 settings.py 안에 있는 아래 녀석이다.
STATIC_URL = '/static/'
이제 크롬에서 강력 새로고침을해보자
저기 오른쪽 마우스 클릭하면나옴
위와 같이 뜨게된다.
이상태에서 그냥 새로고침을하면!?
이런식으로 메모리 캐싱이라고 뜹니다. 이는 나중에 배울 메모리제이싱 , 일종의 캐싱이라 보면됩니다.
저장해놓고 빠르게 보기? 라 생각해보면됩니다.
settings.py에서 다른 곳으로 저장해보자
STATICFILES_DIR = [
#crud/static/stylesheets/style.css
BASE_DIR / 'crud' / 'static',
]
이걸 추가시켜주자.
후에 폴더를 만들어주자 static/ stylesheets / 스타일.css 파일
style.css
h1 {
color: tomato;
}
적용하기
base.html 찾기
css block 시키기 > 타이틀 위에다가
그리고 이놈을 index.html에서 불러와보자.
그리고 사이에 link 를 입력해주고 경로 설정을해주자.
개발자도구를 이용해보자
여기서 저주소를 들어가보자
짜란 코드가 바로뜨게된다.
이미지 파일을 같은 방식으로가게되면 이미지파일만뜨게된다. 즉, 우린 프론트엔드 파츠는 이걸로 볼수있는 것
백엔드말고!
settings.py 로가보자 (배포)
다음 서버를 끄고 아래 명령어를 처주자
python manage.py collectstatic
그려머는 옆에 폴더가 staticfiles가 추가됩니다.
여기까지가 static에 오늘 배움에 대한 전부이다
Media 파일 추가하기 시작
media 파일
settings.py > MEDIA_ROOT, URL 추가 해주기
upload_to 라는 녀석을 통해
이번에도 "django media files" 라고 검색해보자
Managing files
This document describes Django’s file access APIs for files such as those uploaded by a user.
기본적으로 장고는 로컬에 저장한다, media_root와 url 을 사용한다.
Using files in models
When you use a FileField
or ImageField
, Django provides a set of APIs you can use to deal with that file.
모델에서는 filefield와 imagefield를 추가한다.
models.py
image 를 추가시켜주자
이렇게하면 기존에 있던 파일이 이미지가 없기떄문에 다른 뭔가 뜰것임..
그래서 우리는 저중간에 blank=True 를 넣어준다.
from django.db import models
# Create your models here.
class Article(models.Model):
title = models.CharField(max_length=10)
content = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
image = models.ImageField(blank=True)
이제 저장하고 makemigrations 와 migrate를 해주자
ㅇ
에러뜨쥬? 근데 Pillow 가 설치안돼있다고 설치하래요
pip install Pillow
항상 다른 사람을위해서 리콰이어먼트에 추가해주자
pip freeze > requirements.txt
그리고 migrate도 꼭 해주기!
이제 서버를 켜보아요.
create.html 가자
이미지를 띄워봅시다
인크 타입이무엇일까? 참고하러가봅시다. 검색어 " mdn form enctype"
enctype
method
특성이 post
인 경우, enctype
은 양식 제출 시 데이터의 MIME 유형을 나타냅니다.
application/x-www-form-urlencoded
: 기본값.multipart/form-data
:<input type="file">
이 존재하는 경우 사용하세요.text/plain
: HTML 5에서 디버깅 용으로 추가된 값.
`](https://developer.mozilla.org/ko/docs/Web/HTML/Element/button),
(en-US),
(en-US)요소의 [
formenctype` 특성으로 재정의할 수 있습니다.
라고 합니다.
views.py
def create(request):
# POST일 때
if request.method == 'POST':
form = ArticleForm(request.POST, request.FILES)<<<<<<< 파일요청을 추가해주셔야해요
if form.is_valid():
article = form.save()
return redirect('articles:detail', article.pk)
# GET일 때
else:
form = ArticleForm()
context = {
# 상황에 따른 2가지 모습
# 1. is_valid에서 내려온 form : 에러메세지를 포함한 form
# 2. else에서 내려온 form : 빈 form
'form': form,
}
return render(request, 'articles/create.html', context)
settings.py
#미디어 url
#STATIC_ROOT와 유사. 업로드된 파일의 주소를 만들어줌.
MEDIA_URL= '/media/'
#미디어 루트
# 실제 업로드뒤는 파일이 저장되는 경로를 지정
MEDIA_ROOT = BASE_DIR / 'media'
근데 만약에 사용자가 같은 이름으로 저장을한다묜 어떻게할까요?
models.py 에서 구분시키는 코드를 추가시켜줍니다.
from django.db import models
# Create your models here.
class Article(models.Model):
title = models.CharField(max_length=10)
content = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
image = models.ImageField(upload_to ="uploads/%Y/%m/%d",blank=True) #<<< 구분지어주기
장고가 알아서 뒤에 무엇을 붙여줍니다.
templats> detail.html
공식문서에서 name, path, url 을 추가시켜라합니다.
{% extends 'base.html' %}
{% block content %}
<h2>DETAIL</h2>
<h3>{{ article.pk }} 번째 글</h3>
<hr>
<p>제목 : {{ article.title }}</p>
<p>내용 : {{ article.content }}</p>
<img src="{{ article.image.url }}" alt="{{ article.image.name }}">#<<< 이녀석 추가
<p>작성시각 : {{ article.created_at }}</p>
<p>수정시각 : {{ article.updated_at }}</p>
<hr>
<a href="{% url 'articles:update' article.pk %}" class="btn btn-primary">[UPDATE]</a>
<form action="{% url 'articles:delete' article.pk %}" method="POST">
{% csrf_token %}
<button class="btn btn-danger">DELETE</button>
</form>
<a href="{% url 'articles:index' %}">[back]</a>
{% endblock %}
여기까지하면 이렇게뜸 ㅎㅎ;
우리 root urls py로 가보자.
https://docs.djangoproject.com/en/3.1/howto/static-files/여기들어가보면 개발단계에서 유저가 올린것을 보기 탭이있습니다.
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
# ... the rest of your URLconf goes here ...
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
이것들은 장고가 미디어파일을 관리하는 방식이다. 그냥 따라주시면됩니다.
이미지 없을때 안 띄우는 방법!
- if문
{% extends 'base.html' %} {% block content %} <h2>DETAIL</h2> <h3>{{ article.pk }} 번째 글</h3> <hr> <p>제목 : {{ article.title }}</p> <p>내용 : {{ article.content }}</p> {% if article.image %}#<<<<<<<<<<<<<<<<<<<<< <img src="{{ article.image.url }}" alt="{{ article.image.name }}"> {% endif %}#<<<<<<<<<<<<<<<<<<<<<<<< <p>작성시각 : {{ article.created_at }}</p> <p>수정시각 : {{ article.updated_at }}</p> <hr> <a href="{% url 'articles:update' article.pk %}" class="btn btn-primary">[UPDATE]</a> <form action="{% url 'articles:delete' article.pk %}" method="POST"> {% csrf_token %} <button class="btn btn-danger">DELETE</button> </form> <a href="{% url 'articles:index' %}">[back]</a> {% endblock %}
- 기본적 이미지 생성
{% extends 'base.html' %} {% block content %} <h2>DETAIL</h2> <h3>{{ article.pk }} 번째 글</h3> <hr> <p>제목 : {{ article.title }}</p> <p>내용 : {{ article.content }}</p> {% if article.image %} <img src="{{ article.image.url }}" alt="{{ article.image.name }}"> {% elif %} <img src="기본 이미지" alt="{{ article.image.name }}"> #<<<<<<<<<<<<<<<<<<< {% endif %} <p>작성시각 : {{ article.created_at }}</p> <p>수정시각 : {{ article.updated_at }}</p> <hr> <a href="{% url 'articles:update' article.pk %}" class="btn btn-primary">[UPDATE]</a> <form action="{% url 'articles:delete' article.pk %}" method="POST"> {% csrf_token %} <button class="btn btn-danger">DELETE</button> </form> <a href="{% url 'articles:index' %}">[back]</a> {% endblock %}
그리고 같은 파일을 올리면 MD5, Hash 알고리즘 이라하여 희안한 이름을 붙여줍니다.
views.py
update 함수에 enctype="multipart/form-data" 과, requestFILES, 추가시켜주기
@require_http_methods(['GET', 'POST'])
def update(request, pk):
article = Article.objects.get(pk=pk)
# update
if request.method == 'POST':
form = ArticleForm(request.POST, request.FILES, instance=article)
if form.is_valid():
form.save()
return redirect('articles:detail', article.pk)
# edit
else:
form = ArticleForm(instance=article)
context = {
'form': form,
'article': article,
}
return render(request, 'articles/update.html', context)
하지만 장고 미디어파일에는 사진과 글이있는 글을 삭제해도 파일은 남게된다.
기존 이미지 삭제하는 알고리즘을 적어두면된다.
문제
용량제한을 걸어둬야 서버 문제가 줄어든다. 용량 제한을 알아두자.
아이콘 바꾸기
이녀석을 바꿔보자
다운받은 아이콘을 올리자
https://www.favicon-generator.org/ (파일 선택 > create Favicon > 다운로드)
그러면 종류별로 icon 이 생성된 알집이 나오는데 압축을 풀어주고 32*32을 찾아주자
다음 crud > static 안에 넣어주자
base. html 로가자
{% load static %} 맨위에추가
헤드 안 meta 가장 아래에 link 테그를 넣어주자
rel 은"" icon" 으로 변경 주소는"{% static 'favicon-32x32.png' %}"
media 폴더 내 파일도 지우는방법
article.image.delete() 이친구를 views.py 의 딜리트 함수에 추가시켜주면됩니다.
@require_POST
def delete(request, pk):
# 삭제할 게시글 조회
article = Article.objects.get(pk=pk)
# 삭제 요청이 POST면 삭제, POST가 아니라면 DETAIL 페이지로 redirect
article.image.delete() #ArticleCkass.ImageField.method()
article.delete()
return redirect('articles:index')
네비바에 검색어 입력하는방법
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<div class="container-fluid">
<a class="navbar-brand" href="#">Navbar</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="#">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Link</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false">
Dropdown
</a>
<ul class="dropdown-menu" aria-labelledby="navbarDropdown">
<li><a class="dropdown-item" href="#">Action</a></li>
<li><a class="dropdown-item" href="#">Another action</a></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item" href="#">Something else here</a></li>
</ul>
</li>
<li class="nav-item">
<a class="nav-link disabled" href="#" tabindex="-1" aria-disabled="true">Disabled</a>
</li>
</ul>
<form class="d-flex">
<input class="form-control me-2" type="search" placeholder="Search" aria-label="Search">
<button class="btn btn-outline-success" type="submit">Search</button>
</form>
</div>
</div>
</nav>
밑 form에 action="{% url 'articles:search' %}" method="GET">과 input 에 name = "keyword를 추가해줍니다."
를 추가해준다
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<div class="container-fluid">
<a class="navbar-brand" href="#">Navbar</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="#">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Link</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false">
Dropdown
</a>
<ul class="dropdown-menu" aria-labelledby="navbarDropdown">
<li><a class="dropdown-item" href="#">Action</a></li>
<li><a class="dropdown-item" href="#">Another action</a></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item" href="#">Something else here</a></li>
</ul>
</li>
<li class="nav-item">
<a class="nav-link disabled" href="#" tabindex="-1" aria-disabled="true">Disabled</a>
</li>
</ul>
<form class="d-flex" action="{% url 'articles:search' %}" method="GET"> #<<< 여기랑
<input name="keyword" class="form-control me-2" type="search" placeholder="Search" aria-label="Search">#<<여기용!
<button class="btn btn-outline-success" type="submit">Search</button>
</form>
</div>
</div>
</nav>
그다음 urls.py 에서 추가
from django.urls import path
from . import views
app_name = 'articles'
urlpatterns = [
path('index/', views.index, name='index'),
# path('new/', views.new, name='new'),
path('create/', views.create, name='create'),
path('<int:pk>/', views.detail, name='detail'),
path('<int:pk>/delete/', views.delete, name='delete'),
# path('<int:pk>/edit/', views.edit, name='edit'),
path('<int:pk>/update/', views.update, name='update'),
path('search/', views.search, name='search')
]
다음 views.py 에서 search 함수 추가
def search(request):
# 1. 사용자가 입력한 검색어를 꺼냅니다.
keyword = request.GET.get('keyword')
# 2. 검색어에 해당하는 데이터를 DB에서 가져옵니다.
articles = Article.objects.filter(title=keyword)
context = {
'articles':articles,
}
return render(request, 'articles/index.html', context)
필터를 해주고 옆의 () 안에는 title 또는 context 를 입력해주면 keyword값 검색이가능하다.
추가적으로 title__contains 를 하면 keyword를 가진 모든 값을 검색 가능하다.
'SSAFY > Django' 카테고리의 다른 글
[Django]Form (0) | 2021.03.21 |
---|---|
[DJANGO] STATIC FILES (0) | 2021.03.19 |
현재까지 Django 요약 (0) | 2021.03.17 |
가상환경 만들기부터 게시판 Form 을 사용하여 만들기 (0) | 2021.03.16 |
Django 가상 환경 만들기 // 협업 (0) | 2021.03.13 |