9주차 WIL

looggi·2022년 10월 29일
0

스파르타 내배캠 AI-3

목록 보기
51/130
post-thumbnail

🎃 장고 심화 5주차 ~ 끝!

🍭 알게 된 것

  • 코드 테스팅
    파일명/ 함수명이 test로 시작해야 python manage.py test 가 인식해서 실행할 수 있다

  • python manage.py test app_name
    app_name이 없으면 test로 시작하는 테스트코드 함수 모두 실행됨

  • test code를 포함하는 class 는 APITestCase를 상속받는다

  • post 시 response
    url = reverse('url_name')
    data = 전송할 데이터
    response = self.client.post(url, data)

  • 회원가입 코드 테스트 후 로그인 테스트가 실행이 안되는 이유: 테스트마다 db를 초기화하기때문에 회원가입한 데이터가 db에 남아있지 않기때문 ➡ setup 메소드 사용

  • setUp 메소드는 클래스 내부에서 이하 메소드 실행 전 무조건 실행된다
    ↔ tearDown

  • self.assertEqual(arg1,arg2)
    arg1 == arg2 인지 확인해주는 메소드 맞을 경우 ok 리턴

  • 🔎 회원정보 받기

def test_get_user_data(self)
    access_token = self.client.post(reverse('token_obtain_pair'), self.data).data['access']
    response = self.client.get(
                  path = reverse('user_view'),
                  HTTP_AUTHORIZATION = f'Bearer {access_token}'
                  # 헤더에 토큰을 실어 보냄
                  )
	self.assertEqual(response.status_code,200)

  • staticmethod vs classmethod(factorymethod)
    스태틱은 함수 정의시 클래스 내부/외부가 상관이 없으나 코드의 깔끔함을 위해 사용할 클래스 내부에 정의해주는 것이 좋다
    클래스메소드는 인스턴스 생성 전에 실행이 가능하고, 함수 정의시 리턴값이 해당 클래스 재실행인 경우가 많다
    아래 사용된 setUpTestData 메소드는 setUp메소드 실행시 매 test함수 실행 전 반복실행되는 비효율성을 없애준다
class ArticleCreateTest(APITestCase):
	@classmethod
    def setUpTestData(cls):
        cls.user_data = {'username':'Jason','password':'JasonPassword'}
        cls.article_data = {'title':'some title','content':'some content'}
        cls.user = User.objects.create_user('Jason','JasonPassword')

    def setUp(self):
        self.access_token = self.client.post(reverse('token_obtain_pair',self.user_data)).data['access'] 
        # client 메소드는 클래스메소드가 아니기에 cls.client 할 수 없어서 따로 setUp으로 정의해준다 
  • 🔎 게시글 생성하기
def test_create_article(self):
        response=self.client.post(
            path = reverse('article_view'),
            data= self.article_data,
            HTTP_AUTHORIZATION = f"Bearer {self.access_token}")
        self.assertEqual(response.data['message'],'글 작성 완료!')
  • 🔎 이미지 포함된 게시글 생성하기
# 클래스 외부에 정의됨
def get_temporary_image(temp_file):
    size = (200,200)
    color = (255, 0, 0, 0)
    image = Image.new("RGBA", size, color)
    image.save(temp_file,'png')
    return temp_file
def test_create_article_with_image(self):
        temp_file = tempfile.NamedTemporaryFile()
        # 파이썬 자체에서 임시파일 만드는 방법
        temp_file.name = "image.png"
        image_file = get_temporary_image(temp_file)
        image_file.seek(0)
        # 이미지파일의 첫번째 프레임을 받아옴
        # 그냥 파일이기때문에 프레임을 받아오는 것이 필요함
        self.article_data['image'] = image_file
        response = self.client.post(
            path = ('articleview'),
            data = encode_multipart(data=self.article_data, boundary = BOUNDARY),
            content_type = MULTIPART_CONTENT,
            HTTP_AUTHORIZATION = f"Bearer {self.access_token}",
        )
        self.assertEqual(response.status_code, 200)

  • Faker - 더미데이터 만들기
    pip install Faker 후
    from faker import Faker
    faker = Faker() 객체 생성해서 사용
  • 🔎 게시글 상세페이지 조회하기
class ArticleReadTest(APITestCase):
    @classmethod
    def setUpTestdata(cls):
        cls.faker = Faker()
        cls.articles = []
        for i in range(10):
            # 10명의 유저가 각각 하나씩 게시글을 만든다
            cls.user = User.objects.create_user(cls.faker.name(),cls.faker.word())
            # cls.faker.name() -> usernmae, cls.faker.word() -> password 가 됨
            cls.articles.append(Article.objects.create( title = cls.faker.sentence(),
                                                        content = cls.faker.text(),
                                                        user = cls.user,))
    def test_get_article(self):
        for article in self.articles:
            url=article.get_absolute_url()
            response = self.clinet.get(url)
            # 보낼 데이터가 없으니 url만 넣으면 됨
            serializer = ArticleSerializer(article).data
            # 시리얼라이져를 통해 오브젝트(article)를 시리얼라이즈 형태(제이슨형식)로 바꿔줌
            for key, value in serializer.items():
            # .items는 딕셔너리에서 키, 밸류값을 뽑아낼 때 사용한다
            # title, content, user은 키 cls.faker.sth은 밸류
                self.assertEqual(response.data[key],value)
                # -> self.assertEqual(article["title"],response.data["title"]) 이렇게 일일이 안해줘도 됨

🧐 궁금한 것들 정리

📍 트레일링 슬래시(trailing slash)

  • 리소스 종류 구분
    • 붙이면 해당 URL 리소스가 디렉토리(directory)
    • 붙이지 않으면 해당 URL 리소스가 파일(file)
  • URL은 scheme-host-path로 구성
    • 리소스 경로는 도메인(호스트)이후에 path 부분에 명시됨
      ➡ www.naver.com의 경우는 도메인까지만 나와있으므로 /를 붙이나 안붙이나 똑같음
      (리소스 종류를 구분해주는 게 아니다( http request는 경로가 생략될 수 없기에 온전한 url이 아님 ➡ 브라우저가 /(경로)를 붙여줌)
  • <a></a>태그 (앵커태그) 사용시엔 href 부분에 www.naver.com/이렇게 경로까지 붙여주는 게 좋고
    주소가 직접 보여지는 부분엔 /를 떼고 도메인까지만 보여주는 게 보기 좋다

📍 사용자 생성

  • create_user
from django.contrib.auth.models import User
user = User.objects.create_user('john', 'lennon@thebeatles.com', 'johnpassword')

프로젝트에서는 html폼태그 안에 작성한 값을 받아와야했으니까

user = User.objects.create_user(username=username, email=email, password=password) 

이렇게 사용함

📍 비밀번호 해싱

  • model_instance.set_password('raw password')
    set_password()메소드가 객체를 저장까지 하진 않아서
    model_instance.save()까지 해줘야 DB에 저장됨

📍 Authenticating users

  • from django.contrib.auth import autenticate, login, logout

📍 괄호의 종류 : {set},(tuple),[list],{'딕셔너리key':'value'}

📍 HttpRequest는 object..

request.POST.get
객체.objects.get

📍 class Meta

class Meta: 
        # 오름차순 
        ordering = ['필드명']
        
        db_table = '테이블 이름'
        verbose_name = 'admin 페이지에 보이는 이름'

📍 through table

  • articles_article_likes
  • users_user_following
    ➡ symmetrical = True면 from/to 로 나눠지지 않고 서로 연관이 있다는 필드 하나만 생성됨

📍 편집기에서 수정사항 반영이 너무 느릴 땐

터미널을 하나 더 열어서 실행해보면 된다 속이다시원함 휴

📍 Serializer relations

  • serializers.field_name 형태로 사용
  • StringRelatedField : read-only
    models.py 에 정의된 def __str__에 정의된 리턴값으로 해당 필드값을 반환
  • PrimaryKeyRelatedField : read-write but can change into read-only
profile
looooggi

0개의 댓글