recaptcha 는 악의적인 공격을 막기 위한 도구입니다. 구글에서 제공하며 사진, 글자 등으로 로봇과 사람을 구별합니다.

https://www.google.com/recaptcha/ 에서 확인 가능합니다. 


1. views.py 설정

django 에서 recaptcha를 쓰려면 django의 views.py 에서 사용하면 됩니다.

url을 이용해서 request와 response를 다뤄야 하므로 몇 가지를 import해서 불러옵니다.


import urllib
from urllib.parse import urlparse
cs


urllib은 파이썬에서 제공하는 url관련 패키지입니다. urlparse는 그 중에서도 url을 바탕으로 파싱하는 작업을 수행하는 모듈입니다.

이렇게 쓸 도구를 불러와서 서버쪽에서 recaptcha와 데이터를 주고받아서 판단하면 됩니다. 

가입은 구글에서 다른 글들을 검색하면 잘 설명되어 있습니다.


        recaptcha_response = request.POST.get('g-recaptcha-response')
        url = 'https://www.google.com/recaptcha/api/siteverify'
        values = {
            'secret': settings.GOOGLE_RECAPTCHA_SECRET_KEY,
            'response': recaptcha_response
        }
        recaptcha_data = urllib.parse.urlencode(values).encode()
        recaptcha_req = urllib.request.Request(url, data=recaptcha_data)
        recaptcha_response = urllib.request.urlopen(recaptcha_req)
        recaptcha_result = json.loads(recaptcha_response.read().decode())
 
        if not recaptcha_result['success']:
cs


여기서 settings.GOOGLE_RECAPTCHA_SECRET_KEY 자리에 각자 부여받은 키를 쓰면 됩니다.

개발용 서버에서 이용하고 싶을 땐 127.0.0.1을 쓰면 자연스럽게 이용가능합니다.


2. html 템플릿 설정


html 태그에선 header등에 <script></script>를 써 주고 구글이 알려준 코드를 쓰면 됩니다.


<script src='https://www.google.com/recaptcha/api.js'></script>
cs

이것을 써주면 됩니다.


<div class="g-recaptcha" data-sitekey="some value that google gave to you"></div>
 
cs


html 템플릿에는 위의 div를 써주면 recaptcha를 유저가 클라이언트에서 볼 수 있고 클릭할 수 있게 됩니다.

자바는 세계적으로 매우 많이 이용되는 언어입니다. 

자바 : https://java.com/ko/ 

컴파일로 실행되는 언어이며 이용자가 많고 커뮤니티도 활발하여 자료가 많이 존재합니다. 스마트폰의 운영체제인 안드로이드가 기반으로 삼고 있는 언어이기도 합니다. 자바의 초급 단계로 계산기 역할을 하는 helloworld를 만들어보겠습니다.


1. helloworld.java

helloworld.java를 만들어 보겠습니다.

public class HelloWorld {
 
    public static void main(String[] args) {
 
        int a = 21;
        int b = 23;
        Integer insA = new Integer(21);
        Integer insB = new Integer(23);
        
        System.out.println("(bbb) int a: " + a + ", b: " + b);
        System.out.println("(bbb) Integer a: " + a + ", b: " + b);
        System.out.println();
        
        swap(a, b);
        swap(insA, insB);
        System.out.println();
        
        System.out.println("(aaa) int a: " + a + ", b: " + b);
        System.out.println("(aaa) Integer a: " + a + ", b: " + b);
    }
}
cs


int a 는 숫자 변수를 담는 자료형입니다. 그리고 System.out.println()은 괄호 안의 값을 출력하는 함수입니다. 계산 결과를 처리하여 출력하도록 설정했는데 위의 결과와 아래의 결과가 다릅니다. 왜냐하면 java는 아래의 swap같은 함수 처리를 해야 정확히 포인터를 계산해서 출력하기 때문입니다. 


2. swap 함수 작성

swap 함수를 따로 만들겠습니다.


    private static void swap(int a, int b){
        int tttaa = a;
        a = b;
        b = tttaa;
        System.out.println("(funn) int a: " + a + ", b: " + b);
    }
    private static void swap(Integer a, Integer b){
        Integer tttaa = new Integer(a);
        a = b;
        b = tttaa;
        System.out.println("(funn) Integer a: " + a + ", b: " + b);
    }
cs


이렇게 하면 함수를 만들게 됩니다. 스왑함수는 println을 포함합니다. 즉각적으로 바로 확인할 수 있게 하기 위해서입니다.

static void는 리턴되는 값이 없음을 의미합니다. 


3. 문자 입력받기

    private static int scanInt(){
        Scanner scn = new Scanner(System.in);
        int result = scn.nextInt();
        scn.close();
        return result;
    }
cs

그 다음 scanInt를 만들어서 숫자를 읽어들일 수 있도록 합니다. Scanner(System.in)은 키보드를 통한 입력을 받는 함수입니다. 자바에서 기본적으로 제공합니다.


public class Unknown1 {
    private int[] input;
    private int n;
    }
}
cs


이 함수를 통해 System.in을 한 번 살펴보겠습니다

.

    public Unknown1(){
        Scanner scnned = new Scanner(System.in);
         String[] array = scnned.nextLine().split(" ");
         input = new int[array.length];
         for(int i = 0; i < array.length; i++){
             input[i] = Integer.parseInt(array[i]);
         }
         scnned.close();
         
         n = input.length;
    }
cs


이 함수를 저기 위의 함수 안에 넣어주도록 합니다. ArrayList를 이용해서 주어진 숫자를 조작하는 함수입니다. 입력받는 인자는 여러번 연속적으로 주어질 수 있으므로 array 를 이용하여 작성합니다. 그러므로 for문을 이용해서 인자가 입력받을 때마다 array에 문자열을 입력하게 됩니다.


1. models.py


models.py에서 사전설정을 합니다.


GAME_STATUS_CHOICES = (
    ("F""First turn Player"),
    ("S""Second turn Player"),
    ("W""First Player has Win"),
    ("L""Second Player has Win"),
    ("D""Draw")
)
cs


views.py에서 보내진 인자에 따라 models.py를 결정할 수 있게 됩니다.

각각 머리글자를 따서 튜플 형태로 작성합니다.


class GamesQuerySet(models.QuerySet):
    def games_user(self, user):
        return self.filter(
            Q(first_player=user) | Q(second_player=user)
        )
 
    def is_active(self):
        return self.filter(
            Q(status='F'| Q(status='S')
        )
 
    def drew_games(self):
        return self.filter(status='D')
cs

여기서 Q를 쓰고 filter를 바로 써 줄 수 있습니다. 좀 더 편리한 코드 작성이 가능합니다.


class Game(models.Model):
    first_turn_player = models.ForeignKey(User, on_delete=models.CASCADE, related_name="first_player")
    second_turn_player = models.ForeignKey(User, on_delete=models.CASCADE, related_name="second_player")
 
    start_datetime = models.DateTimeField(auto_now_add=True)
    end_datetime = models.DateTimeField(auto_now=True)
    status = models.CharField(max_length=1default='F', choices=GAME_STATUS_CHOICES)
 
    objects = GamesQuerySet.as_manager()
 
    def __str__(self):
        return "{0} vs {1}".format(self.first_player, self.second_player)
cs


데이터베이스 사용시엔 필연적으로 model을 지정해야 합니다.

manager도 사용해봤습니다. 그 후 이동에 관련된 모델을 지정합니다.


class Move(models.Model):
    x = models.IntegerField()
    y = models.IntegerField()
    comment = models.CharField(max_length=300, blank=True)
    by_first_player = models.BooleanField()
 
    game = models.ForeignKey(Game, on_delete=models.CASCADE)
cs


이렇게 이동하는 동작을 모델로 지정해줘도 괜찮습니다. 데이터베이스를 이용할 것이니 모델로 지정해주는 것이 ORM사용에도 유리할 것입니다.

유저의 기본정보를 묻는 모델도 만듭니다.

질문 모델은 이런식으로 할 수 있을 것입니다.


class Question(models.Model):
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField('published')
 
    def recent_published(self):
        now = timezone.now()
        return now - datetime.timedelta(days=1<= self.pub_date <= now
 
    recent_published.admin_order_field = 'pub_date'
    recent_published.boolean = True
    recent_published.short_description = 'recently created'
 
    def __str__(self):
        return self.question_text
cs


def recent_published(self):를 이용하여 최근에 작성되었는지에 대한 여부를 나타내는 함수를 지정했습니다.

유저는 여기에 있는 질문을 받게 됩니다. 그건 views.py를 이용해서 작성해주시면 됩니다. 

2. admin.py

admin에는 ModelAdmin class를 추가해줍니다.


@admin.register(Game)
class GameAdmin(admin.ModelAdmin):
    display = ("id""first_turn_player""second_turn_player""status")
    editable = ("status", )
 
admin.site.register(Move)
cs


게임플레이 자체는 따로 앱을 지정해서 만듭니다. views.py는 아래와 같이 쓸 수 있을 것입니다.


3. 플레이 관련 앱 - views.py


from gameplay.models import Game
 
@login_required
def home(request):
    my_games = Game.objects.games_for_user(request.user)
    active_games = my_games.active()
    drew_games = my_games.drew_games()
 
    return render(request, "home.html", {"num_games": Game.objects.count(),
                                                "games": active_games,
                                                "drew_games": drew_games})
cs


로그인한 사용자만 이용할 수 있게 한 것입니다.

active()와 drew_games()는 새로 지정해줘야합니다.

render시에 num_games에 게임의 객체의 수를 넣어줍니다. home.html에서 사용될 것입니다.


4. html 템플릿


부트스트랩을 쓰면 템플릿은 이렇게 할 수 있을 것입니다. 기본 로그인 화면입니다. 나머지 게임 화면은 원하시는대로 만드시면 됩니다. 기본 로그인 화면은 예시에 불과합니다.


    <body>
    <nav class="navbar navbar-inverse navbar-fixed-top" role="navigation">
      <div class="container">
        <div class="navbar-header">
          <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
            <span class="sr-only">Toggle navigation - 보이지 않는 요소입니다.</span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
          </button>
          <class="navbar-brand" href="/">게임 제목 입니다.</a>
        </div>
        <div id="navbar" class="navbar-collapse collapse">
          <form class="navbar-form navbar-right" role="form">
            <div class="form-group">
<p><h2>이메일</h2></p>
              <input type="text" placeholder="Email" class="form-control">
            </div>
            <div class="form-group">
<p><h2>패스워드</h2></p>
              <input type="password" placeholder="Password" class="form-control">
            </div>
            <button type="submit" class="btn btn-success">Sign in or Login</button>
          </form>
        </div>
      </div>
    </nav>
 
    <div class="container">
 
        {% block content %}
        {% endblock %}
 
    </div>



+ Recent posts