이미지 URL을 imagefield를 사용하여 저장, APIView를 새로 만들기
17258 단어 장고
· 이미지 URL을 imagefield를 사용하여 저장
· APIView를 새로 만들기
참고 기사
Django save image from url and connect with ImageField
imagefield 저장 방법
URL에서 이미지를 검색하고 싶습니다.
imagefield와 URLfield를 가진 모델 만들기
여기에서는, instagram의 이미지를 보존하고 싶기 때문에 「MediaPost」라고 하는 모델 클래스를 정의해, 그 안의 필드 오브젝트로서 「image_name」, 「image」, 「image_url」를 작성하고 있습니다.
그리고 User model과의 연결을 한다.
models.pyfrom django.db import models
from django.contrib.auth.models import User
class MediaPost(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
image_name = models.CharField(max_length=500)
image = models.ImageField(max_length=100, null=True, blank=True, upload_to='medias')
image_url = models.URLField(max_length=1000)
def __str__(self):
return str(self.id)
이미지 URL을 데이터로 저장합니다.
다음으로 학습을 위해 한 번 shell(ipython)로 imagefield에 이미지를 저장해 본다. 우선 이미지 URL을 저장하여 데이터로 열 수 있습니다.
사용할 라이브러리/함수
· urllib.request/URL을 여는 확장 가능한 라이브러리
· urlretrieve/URL을 통해 이미지 데이터를 얻고 일시적으로 저장하는 함수
In [1]: from core.models import MediaPost
In [2]: igpost = MediaPost.objects.first()
In [3]: igpost.image_url
Out[3]: 'https://scontent-nrt1-1.cdninstagram.com/v/t51.29350-15/109130871_149225830105794_6871359187132379915_n.jpg?_nc_cat=107&ccb=1-3&_nc_sid=8ae9d6&_nc_ohc=QnKpVyNkJ7YAX-2HEmk&_nc_ht=scontent-nrt1-1.cdninstagram.com&oh=cca63e1391b65a1478c5e97d445336cb&oe=606F1FBB'
In [4]: from urllib import request
In [5]: result = request.urlretrieve(igpost.image_url)
In [6]: result
Out[6]:
('/var/folders/pl/c0lccdcn32ggnndflmf9r6yh0000gn/T/tmpiazqg0da',
<http.client.HTTPMessage at 0x1105f09d0>)
변수 result의 결과는 tuple형이다./var/folders/pl/c0lccdcn32ggnndflmf9r6yh0000gn/T/tmpiazqg0da
의 /var/folders/pl/c0lccdcn32ggnndflmf9r6yh0000gn/T
파일 위치,tmpiazqg0da
파일 이름을 가지고 있기 때문에 새 터미널을 열고
open /var/folders/pl/c0lccdcn32ggnndflmf9r6yh0000gn/T
그러면 이미지가 저장된 파일이 열립니다. 거기서 방금 저장한 imagefile을 찾아 열면 무사 화상의 보존이 되어 있는 것을 확인할 수 있다.
앞에서도 설명했지만 result의 결과는 tuple형이다. tuple 형과 list 형은 매우 비슷하기 때문에 여기서 차이를 확인합시다.
list... 뮤터블(가변)
tuple...이뮤터블(불변)
즉 tuple은 덮어쓸 수 없다는 것이다.
list,tuple을 정의하는 방법
#list型
>>> list = ["apple", "grape"]
>>> print(list)
['apple', 'grape']
#tuple型
>>> tuple = ("baseball", "soccer", "basketball")
>>> print(tuple)
('baseball', 'soccer', 'basketball')
저장된 이미지 URL의 파일 열기
사용하는 지식
바이너리 파일 읽기 (open(file name, "rb"))
바이너리 파일을 읽어들이기 위해서 파일을 열 경우, open 함수의 모드로서 "r"에 "b"를 더한 "rb"를 지정해 다음과 같이 실행합니다.
※ open 함수는 Python의 함수의 하나로, 파일의 신규 작성이나 보존, 기입 등 파일 조작을 할 수 있습니다.
f = open('FileName', 'rb')
File()/초기설정시에 만들어지는 파일 클래스 의 속성을 이용할 수 있다.
다음에 쉘상에서 file를 폴더 보존한 후에 모델의 image field에도 보존한다.
In [9]: f = open(result[0], 'rb')
In [10]: f
Out[10]: <_io.BufferedReader name='/var/folders/pl/c0lccdcn32ggnndflmf9r6yh0000gn/T/tmpiazqg0da'>
In [12]: from django.core.files import File
In [13]: ig_file = File(f)
In [21]: igpost.image.save(str(uuid.uuid4()),ig_file)
In [22]: igpost
Out[22]: <MediaPost: 1>
In [23]: igpost.save()
이제 무사히 MediaPost 모델의 image field를 저장할 수 있었다.
APIView 만들기
View 구현 (클래스 기반 및 함수 기반)
여기에서는 클래스 기반 APIViews 를 만든다. HTTP의 메소드가 클래스의 메소드가 되기 때문에, 알기 쉽다.
views.pyfrom rest_framework import views, response
from linebot import LineBotApi
from linebot.models import TextSendMessage
from linebot.exceptions import LineBotApiError
class LineWebHookView(views.APIView):
def post(self, request):
line_bot_api = LineBotApi('6uwpQB6+n8WdqkWPQIPYEiuh168/EPrOSdhmwBf813v9MSq4F3JqZ7V4wCAan3BBH7/sKrfNLzHFmHIfN3z9cefAfAh+yos1feTZCUORRCTsTe0tBLNIHJzLPNMTzN4Oj6n1wwxf6CyVFxugHa9kAwdB04t89/1O/w1cDnyilFU=')
user_id = request.data['events'][0]['source']['userId']
try:
line_bot_api.push_message(user_id, TextSendMessage(text='http://localhost:8080/login/' + '?user_id=' + user_id))
except LineBotApiError as e:
print(e)
return response.Response({'status': 'Ok'})
・post를 핸들링 한다
마지막 기사 에서 취득한 row body
의 내용을 Json 형식 포맷을 사용해 정돈한다.
여기에 쓴 코드의 request의 내용은 request.data에서 확인할 수 있다. 이제 line_user_id를 받았기 때문에user_id=request.data['events'][0]['source']['userId']
([json 형식( https://jsonformatter.curiousconcept.com/#)를 사용하여 올바른 형태의 json을 얻습니다. )
라우팅 구현
다음으로 url을 설정해 간다.
urls.pyfrom django.contrib import admin
from django.conf import settings
from django.conf.urls.static import static
from rest_framework import routers
from core.viewsets import UserViewSet, AccountViewSet, FbPostViewSet, IgPostViewSet, MediaPostViewSet
+ from core.views import LineWebHookView
from django.urls import path, include
router = routers.DefaultRouter()
router.register(r'users', UserViewSet)
router.register(r'accounts', AccountViewSet)
router.register(r'fbposts', FbPostViewSet)
router.register(r'igposts', IgPostViewSet)
router.register(r'mediaposts', MediaPostViewSet)
urlpatterns = [
path('admin/', admin.site.urls),
path('', include(router.urls)),
path('api-auth/', include('rest_framework.urls', namespace = 'rest_framework')),
+ path('line-webhook/', LineWebHookView.as_view())
]
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
as_view는 Django 뷰의 조건을 만족하는 함수
여기까지 완성하면 APIViews가 완성되었다고 할 수 있다. django api로 되돌아갈 만큼 지정한 URL에 액세스하면
이 페이지가 열려 있으면 성공이다! content 안에 Json 형식으로 저장한 값을 content 안에 넣는다.
그러면 실행되어 Line 메시지를 송신한다.
오늘의 과제
프런트 엔드에서 instagram 또는 facebook 중 하나로 로그인하지 않은 경우 다른 쪽에서도 로그인하도록 연결 버튼을 추가합니다.
Reference
이 문제에 관하여(이미지 URL을 imagefield를 사용하여 저장, APIView를 새로 만들기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/1999-07-08/items/4359fdafd6f719caf507
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
from django.db import models
from django.contrib.auth.models import User
class MediaPost(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
image_name = models.CharField(max_length=500)
image = models.ImageField(max_length=100, null=True, blank=True, upload_to='medias')
image_url = models.URLField(max_length=1000)
def __str__(self):
return str(self.id)
In [1]: from core.models import MediaPost
In [2]: igpost = MediaPost.objects.first()
In [3]: igpost.image_url
Out[3]: 'https://scontent-nrt1-1.cdninstagram.com/v/t51.29350-15/109130871_149225830105794_6871359187132379915_n.jpg?_nc_cat=107&ccb=1-3&_nc_sid=8ae9d6&_nc_ohc=QnKpVyNkJ7YAX-2HEmk&_nc_ht=scontent-nrt1-1.cdninstagram.com&oh=cca63e1391b65a1478c5e97d445336cb&oe=606F1FBB'
In [4]: from urllib import request
In [5]: result = request.urlretrieve(igpost.image_url)
In [6]: result
Out[6]:
('/var/folders/pl/c0lccdcn32ggnndflmf9r6yh0000gn/T/tmpiazqg0da',
<http.client.HTTPMessage at 0x1105f09d0>)
open /var/folders/pl/c0lccdcn32ggnndflmf9r6yh0000gn/T
#list型
>>> list = ["apple", "grape"]
>>> print(list)
['apple', 'grape']
#tuple型
>>> tuple = ("baseball", "soccer", "basketball")
>>> print(tuple)
('baseball', 'soccer', 'basketball')
f = open('FileName', 'rb')
In [9]: f = open(result[0], 'rb')
In [10]: f
Out[10]: <_io.BufferedReader name='/var/folders/pl/c0lccdcn32ggnndflmf9r6yh0000gn/T/tmpiazqg0da'>
In [12]: from django.core.files import File
In [13]: ig_file = File(f)
In [21]: igpost.image.save(str(uuid.uuid4()),ig_file)
In [22]: igpost
Out[22]: <MediaPost: 1>
In [23]: igpost.save()
View 구현 (클래스 기반 및 함수 기반)
여기에서는 클래스 기반 APIViews 를 만든다. HTTP의 메소드가 클래스의 메소드가 되기 때문에, 알기 쉽다.
views.py
from rest_framework import views, response
from linebot import LineBotApi
from linebot.models import TextSendMessage
from linebot.exceptions import LineBotApiError
class LineWebHookView(views.APIView):
def post(self, request):
line_bot_api = LineBotApi('6uwpQB6+n8WdqkWPQIPYEiuh168/EPrOSdhmwBf813v9MSq4F3JqZ7V4wCAan3BBH7/sKrfNLzHFmHIfN3z9cefAfAh+yos1feTZCUORRCTsTe0tBLNIHJzLPNMTzN4Oj6n1wwxf6CyVFxugHa9kAwdB04t89/1O/w1cDnyilFU=')
user_id = request.data['events'][0]['source']['userId']
try:
line_bot_api.push_message(user_id, TextSendMessage(text='http://localhost:8080/login/' + '?user_id=' + user_id))
except LineBotApiError as e:
print(e)
return response.Response({'status': 'Ok'})
・post를 핸들링 한다
마지막 기사 에서 취득한
row body
의 내용을 Json 형식 포맷을 사용해 정돈한다.여기에 쓴 코드의 request의 내용은 request.data에서 확인할 수 있다. 이제 line_user_id를 받았기 때문에
user_id=request.data['events'][0]['source']['userId']
([json 형식( https://jsonformatter.curiousconcept.com/#)를 사용하여 올바른 형태의 json을 얻습니다. )라우팅 구현
다음으로 url을 설정해 간다.
urls.py
from django.contrib import admin
from django.conf import settings
from django.conf.urls.static import static
from rest_framework import routers
from core.viewsets import UserViewSet, AccountViewSet, FbPostViewSet, IgPostViewSet, MediaPostViewSet
+ from core.views import LineWebHookView
from django.urls import path, include
router = routers.DefaultRouter()
router.register(r'users', UserViewSet)
router.register(r'accounts', AccountViewSet)
router.register(r'fbposts', FbPostViewSet)
router.register(r'igposts', IgPostViewSet)
router.register(r'mediaposts', MediaPostViewSet)
urlpatterns = [
path('admin/', admin.site.urls),
path('', include(router.urls)),
path('api-auth/', include('rest_framework.urls', namespace = 'rest_framework')),
+ path('line-webhook/', LineWebHookView.as_view())
]
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
as_view는 Django 뷰의 조건을 만족하는 함수
여기까지 완성하면 APIViews가 완성되었다고 할 수 있다. django api로 되돌아갈 만큼 지정한 URL에 액세스하면
이 페이지가 열려 있으면 성공이다! content 안에 Json 형식으로 저장한 값을 content 안에 넣는다.
그러면 실행되어 Line 메시지를 송신한다.
오늘의 과제
프런트 엔드에서 instagram 또는 facebook 중 하나로 로그인하지 않은 경우 다른 쪽에서도 로그인하도록 연결 버튼을 추가합니다.
Reference
이 문제에 관하여(이미지 URL을 imagefield를 사용하여 저장, APIView를 새로 만들기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/1999-07-08/items/4359fdafd6f719caf507
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Reference
이 문제에 관하여(이미지 URL을 imagefield를 사용하여 저장, APIView를 새로 만들기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/1999-07-08/items/4359fdafd6f719caf507텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)