아무래도 프로젝트 설정파일을 못읽는거같아서 os.environ["DJANGO_SETTINGS_MODULE"] = "backend.settings" 이 부분을 수정했더니 잘 됩니다. !! 감사합니다. os.environ["DJANGO_SETTINGS_MODULE"] = "backend.settings.settings로 바꿨어용 "
덕분에 원하는 기능을 구현했어요 한개의 게시물이 있고 게시물에는 원하는대로 첨부파일을 넣을수 있는거죠 그리고 원하는대로 삭제하거나 중간만 업데이트 하거나 등등.. 근데 이게 업데이트 할때랑 create할때랑 좀 로직이 바뀌어야되는거같아요 DRF 강력하긴 한데, 너무 강력해서 이게 커스터마이징하는데 투자시간이 너무 많이 드네요 ㅠ from rest_framework import serializers from rest_framework.serializers import raise_errors_on_nested_writes from rest_framework.utils import model_meta from .models import NoticeBoard , NoticeBoardFile , NoticeBoardComment class NoticeBoardFileSerializers(serializers.ModelSerializer): file = serializers.FileField( use_url = True ) class Meta: model = NoticeBoardFile fields = '__all__' def to_internal_value ( self , data): data[ 'name' ] = data[ 'file' ].name return super ().to_internal_value(data) def to_representation ( self , instance): representation = super ().to_representation(instance) representation.update( { "size" : instance.file.size , } ) return representation class NoticeBoardListSerializers(serializers.ModelSerializer): author = serializers.CharField( source = 'author.fullname' ) class Meta: model = NoticeBoard fields = [ 'id' , 'title' , 'is_public' , 'updated_at' , 'author' , 'views' ] class NoticeBoardRetrieveSerializers(serializers.ModelSerializer): author = serializers.CharField( source = 'author.fullname' ) noticeboardfile_set = NoticeBoardFileSerializers( many = True ) class Meta: model = NoticeBoard fields = '__all__' def validate ( self , attrs): attrs = super ().validate(attrs) request = self .context[ 'request' ] uploaded_files = [] if request.data.getlist( 'file' ): for uploaded_file in request.data.getlist( 'file' ): print ( type (uploaded_file)) # print(uploaded_file.name) # serializer = NoticeBoardFileSerializers(data={'file': uploaded_file}) # serializer.is_valid(raise_exception=True) uploaded_files.append(uploaded_file) attrs[ 'file' ] = uploaded_files print (attrs) return attrs else : return attrs def update ( self , instance , validated_data): raise_errors_on_nested_writes( 'update' , self , validated_data) info = model_meta.get_field_info(instance) uploaded_files = [] file_object_list = [] str_list = [] already_uploaded_file_list = [] already_uploaded_file_list_temp = NoticeBoardFile.objects.filter( post =instance).values_list( 'id' , flat = True ) for temp in already_uploaded_file_list_temp: already_uploaded_file_list.append(temp) print ( 'start' , already_uploaded_file_list) if 'file' in validated_data: uploaded_files = validated_data.pop( 'file' ) if len (uploaded_files) > 0 : for uploaded_file in uploaded_files: print (uploaded_file , type (uploaded_file)) if type (uploaded_file) == str : str_list.append(uploaded_file) continue else : file_object_list.append( NoticeBoardFile( post =instance , file =uploaded_file , name =uploaded_file.name)) NoticeBoardFile.objects.bulk_create(file_object_list) else : NoticeBoardFile.objects.filter( post =instance).delete() print (str_list , 'str_list' ) print ( 'already_uploaded_file_list' , already_uploaded_file_list) for already_uploaded_file in already_uploaded_file_list: print (already_uploaded_file) if str (already_uploaded_file) in str_list: continue if not str (already_uploaded_file) in str_list: print (already_uploaded_file , ' 는 없다 .' ) NoticeBoardFile.objects.get( id =already_uploaded_file).delete() # Simply set each attribute on the instance, and then save it. # Note that unlike `.create()` we don't need to treat many-to-many # relationships as being a special case. During updates we already # have an instance pk for the relationships to be associated with. m2m_fields = [] for attr , value in validated_data.items(): if attr in info.relations and info.relations[attr].to_many: m2m_fields.append((attr , value)) else : setattr (instance , attr , value) instance.save() # Note that many-to-many fields are set after updating instance. # Setting m2m fields triggers signals which could potentially change # updated instance and we do not want it to collide with .update() for attr , value in m2m_fields: field = getattr (instance , attr) field.set(value) return instance class NoticeBoardCreateSerializers(serializers.ModelSerializer): class Meta: model = NoticeBoard fields = [ 'title' , 'content' , 'author' ] def validate ( self , attrs): attrs = super ().validate(attrs) request = self .context[ 'request' ] uploaded_files = [] if request.data.getlist( 'file' ): for uploaded_file in request.data.getlist( 'file' ): print ( type (uploaded_file)) print (uploaded_file.name) # serializer = NoticeBoardFileSerializers(data={'file': uploaded_file}) # serializer.is_valid(raise_exception=True) uploaded_files.append(uploaded_file) attrs[ 'file' ] = uploaded_files return attrs else : return attrs def create ( self , validated_data): uploaded_files = [] file_object_list = [] if 'file' in validated_data: uploaded_files = validated_data.pop( 'file' ) post = super ().create(validated_data) if len (uploaded_files) > 0 : for uploaded_file in uploaded_files: file_object_list.append(NoticeBoardFile( post =post , file =uploaded_file , name =uploaded_file.name)) NoticeBoardFile.objects.bulk_create(file_object_list) return post def to_representation ( self , instance): representation = super ().to_representation(instance) representation.update( { "id" : instance.id , } ) return representation
def validate ( self , attrs): attrs = super ().validate(attrs) 질문 1 이 validate는 상속받아서 구현하는건 알겠는데 attrs = super().validate(attrs) 이부분은 왜 하는걸까요? ㅠ 진짜 파이썬에 대해서 하나도 모른다는걸 실감하네요 ㅠ 질문 2 self.context['request'] 이 부분인데 의미를 더 알고 싶습니다. self.context 이부분이요 질문 3 그럼 로직이 일단 시리얼라이즈가 뷰에서 호출되면 validate 함수가 발동이 되면서 이걸 호출해서 검증을 해주면 되고 이 attrs 결과가 validated_data로 들어가는거죠? 질문4 drf에 serializers.ImageField가 있는데 모델에서 이미지필드가 있다면 따로 적용안해도 되는부분인가요.??