인프런 커뮤니티 질문&답변

이광현님의 프로필 이미지

작성한 질문수

파이썬/장고 웹서비스 개발 완벽 가이드 with 리액트

크롤링한 이미지데이터를 데이터베이스에 넣기 ??

23.03.24 14:29 작성

·

1.3K

1

안녕하세요 교수님 django를 활용한 웹페이지로 졸업작품을 하려는 대학생입니다.

서론이 길어질 수 있는데, 최대한 짧게 말씀드리자면, 사용자가 원하는 키워드를 입력하면 자동적으로 구글에서 이미지 크롤링을 하여 원하는 개수만큼 다운받은 후 AI쪽 이미지 생성 모델을 통하여 제가 원하는 방향으로 나오게 하는 웹페이지입니다(정확히는 뭐 ai를 활용한 상담 컬러링북)이였는데 보여줄 방법이 웹과 앱중 고민하던 중 웹을 선택했고 그 중에 제가 공부한 django 를 활용할 계획입니다.

여기서 저의 질문(목표)은 처음 키워드와 검색할 이미지 개수를 폼에다 입력을 하면 키워드와 그 키워드로 크롤링을 하고 크롤링된 이미지(예를들어서 3개)를 데이터베이스에 저장을 하고 싶은 상황입니다, (우선 이미지 1장을 저장하는 것으로 목표를 설정했습니다,. 여러장은 한장이 가능해지면 어렵지는 않을 것이라고 생각하고 있습니다)

아래 처럼 모델을 설정해놨고 폼은 modelForm을 사용했습니다,

질문_2.PNG질문_3.PNG

참고로 크롤링하는 코드쪽은 잘 작동하고 numpy, pillow등 원하는 이미지형태로도 바꿀 수 있고 다운까지 다 되는 코드입니다,

views.png

우선 제가 시도했던 방법들입니다. pillow_image는 제가 임의로 다운받은 pil형태의 이미지입니다.

1.처음 폼에 입력했을 때 cleand_data이고 저기에는 이미지는 없는상태입니다,)

2. 그냥 임의로 (크롤링했다고 가정한)이미지를 출력해본 결과입니다,

3, clean_data에 이미지필드(키)에 이미지를 직접넣어서 다시 cleand_data를 넣었는데 출력해보니 아래 그림처럼 <File:None>으로 나오는 상황입니다,

또 다른 방법은 아래 그림처럼 cleand_data에서 직접 입력을 받아와서 새로(?) 넣는 방법입니다

이 방법이 뭔가 가능성이 있어 보였지만 애초에는 저는 폼에 입력한게 아닌따로 이미지를 얻어와서 저장하는 거라 requet.files.getlist라는 것을 쓸 수 가 없었습니다,

 

이 외에도 구글을 정말 뒤져서 몇날 며칠을 시도해 봤지만. 임의의 이미지를 따로 넣는게 정말 어려운 것 같습니다. 혹시 제가 놓치는 부분이 있을 수도 있구요

애초에 이런 방법이 없는 것인가요? 아니면 방법이 있다면 어떤 식이 좋을까요?

(제가 말주변이 없어서 좀 정신없었다면 죄송합니다)

답변 3

1

이진석님의 프로필 이미지
이진석
지식공유자

2023. 03. 25. 13:54

장고 FileField/ImageField에서는 저장 경로를 계산 시에 파일명이 필요합니다.

그러니 jpg 파일이라면 noname.jpg 등과 같이 파일명을 name 인자로 지정이 필요합니다. 외부에서 파일을 업로드받을 때에도 파일내용과 함께 파일명도 함께 전달됩니다.

직접 파일을 생성하신 경우라면, 확장자만 맞추시고 나머지 이름은 임의로 지정하시면 됩니다. 파일명이 중복된다고 해서, 장고에서는 다른 파일을 덮어쓰기 하지 않고 임의의 더미 문자열을 붙여주기 때문에 안심하셔도 됩니다.

그리고 File 에서 파일 객체 지정 시에는
Pillow 객체는 파일 객체가 아니므로, .fp 속성이 파일객체 인터페이스를 구현하고 있으니
File(pillow_instance.fp) 처럼 활용하실 수 있습니다.

화이팅입니다. :-)

1

이진석님의 프로필 이미지
이진석
지식공유자

2023. 03. 24. 15:13

안녕하세요.

searchForm 클래스의 Meta.fields 에는 유저로부터 입력받을 필드들을 나열합니다.

searh_result_image 필드는 유저로부터 입력받는 것이 아니라, 서버에서 입력하는 필드이므로 Meta.fields 속성에서는 빼는 것이 맞을 듯 합니다.

Form 인스턴스는 유저의 입력값을 검사하고 전달받는 목적으로만 사용하면, 문제가 간단해집니다.

서버 단에서 저장 시에 advice 인스턴스가 있으니, 아래처럼 advice.searh_result_image의 .save 메서드를 활용하여 파일 저장을 하실 수 있습니다.

name = "..." # 파일명 지정
advice.searh_result_image.save(name, File(저장할 파일객체), save=False)
advice.save()

관련 공식문서 : https://docs.djangoproject.com/en/4.1/ref/models/fields/#django.db.models.fields.files.FieldFile.save

차근차근 살펴보시고, 댓글 남겨주세요.

진행하시는 졸업작품. 응원합니다. ;-)

0

이광현님의 프로필 이미지
이광현
질문자

2023. 04. 03. 20:15

제가 중간에 다른 해야 할 것들이 있어서 이제서야 답변을 보고 해보고 이미지를 크롤링하여 그 이미지를 화면에 띄우는 것 까지 성공했습니다. 감사합니다,

다만 저의 모델 설계인데 문제는 다수의 이미지를 크롤링하여 화면에 보여줘야 하는데 이럴 경우 저렇게 하나의 필드에 다수의 이미지를 넣어서 template에 보여지는게 가능한가요? 아니면 advice모델과 따로 뭐 image모델을 만들어서 Many To Many 나 Foreignkey로 해야 하나요?

여러 시행착오를 거쳐서 chatgpt에 물어보니

def advice_list(request):
    advice_list = Advice.objects.all()
    context = {'advice_list': advice_list}
    return render(request, 'advice_list.html', context)

###### template##########
{% for advice in advice_list %}
    <h2>{{ advice.keyword }}</h2>
    {% if advice.searh_result_image %}
        <img src="{{ advice.searh_result_image.url }}" alt="search result image">
    {% endif %}
{% endfor %}

이런식으로 하라 하더라구요 하지만 저런식으로

했을 떄도 하나의 이미지만 계속해서 나옵니다,

저의 코드의 에러가 있는건지 애초에 불가능한 건지 잘 모르겠습니다.

 

말이 길어졌는데 요약하면

하나의 이미지 필드에 다수의 이미지를 넣어서 보여지는게 가능한가? 아니면 모델을 따로 만들어 관계 조건을 설정하여 보여지게 해야하나요?

 

매번 답변을 해주셔서 감사합니다,...

이광현님의 프로필 이미지
이광현
질문자

2023. 04. 03. 20:57

죄송합니다. ..

또 막 찾고 시도해보다가 아래와 같은 형식으로 하니까 또 성공했습니다.

물론 하드코딩이지만 저것을 더 간편하게 반복문이라던지 하면 방법이 보일 꺼 같습니다. 도저히 몰라서 질문한건데

 

우연치 않게 방법을 찾아서;;; '' 다음엔 정말정말 모르겠을 때 질문하겠습니다,..

 

adivces1= Advice.objects.create(customer='a',keyword=keyword,find_image_number=1,searh_result_image=path_list[0]+file_name_list[0])   
adivces2= Advice.objects.create(customer='a',keyword=keyword,find_image_number=2,searh_result_image=path_list[1]+file_name_list[1])                                     
advice_list = Advice.objects.all()
이진석님의 프로필 이미지
이진석
지식공유자

2023. 04. 03. 21:47

하나의 models.FileField 혹은 models.ImageField에는 하나의 파일에 대한 경로를 담습니다. models.FileField/ImageField를 활용해서 여러 파일들을 저장하실려면,
설계하기 나름이겠지만, 그 수 만큼 모델필드를 정의하시거나, Image와 같은 별도의 모델을 만드시어 Advice와 1:N 관계 (그럼 models.ForeignKey를 쓰겠죠.) 로 매핑하시는 방법이 있을 수 있습니다.

그리고, 하나의 Advice에 다수의 이미지를 저장하실려는 의도이신 듯 한데요.
댓글에서 시도하신 것은 하나의 Advice로 저장할 것을 굳이 다수의 Advice로 저장하신 것으로 보여집니다.

차근차근 살펴보시고, 또 질문 남겨주세요.

화이팅입니다. :-)

이광현님의 프로필 이미지
이광현
질문자

2023. 04. 03. 23:10

한가지만 더 여쭈어 보겠습니다,,

하나의 Advice에 다수의 이미지를 저장하실려는 의도이신 듯 한데요.

네 제가 크롤링한 다수의 이미지를 저장하고 싶습니다. 저도 마지막 코드를 작성하면서 뭔가 실행은 되지만 좀 비효율적?인 느낌을 받았습니다.

하나의 Advice로 저장할 것을 굳이 다수의 Advice로 저장하신 것으로 보여집니다.

그럼 하나의 Advice에 다수의 이미지로 저장을 하려면 n:1로 하는 것이 효율적이고 깔끔? 할까요?

솔직히 말하면 하나의 필드에 다수의 이미지를 저장하는것이 쉬어보이지만 뒤로 갈수록 웹의 크기가 커지면 문제가 생길꺼 같아 여쭈어 봅니다.

매번 감사합니다.

이진석님의 프로필 이미지
이진석
지식공유자

2023. 04. 05. 12:35

말씀하시는 "느낌"이 무엇을 말씀하시는 것인지 잘 모르겠습니다.

생각하시는 방향에 대한 예시와 그에 대한 생각의 근거도 구체적으로 질문주시면, 보다 좋은 답변을 드릴 수 있을 듯 합니다.

이광현님의 프로필 이미지
이광현
질문자

2023. 04. 08. 22:02

제가 좀 애매한 질문한 한 거 같네요. ㅎㅎ;

결론부터 말씀드리자면 결국 N:1(models.ForeignKey)를 사용하여 크롤링된 이미지를 데이터베이스에 넣는 것과 화면에 보여지게 되는 것 까지 다 해결한 상태입니다

이제 pytorch를 사용하여 이미지 변환과 배포 만이 남았는데 또 모르는 것이 있으면 질문하러 오겠습니다. 항상 감사합니다.