mirror of
https://github.com/evennia/evennia.git
synced 2026-03-16 21:06:30 +01:00
parent
06bc3c8bcd
commit
a452434ba8
663 changed files with 61705 additions and 2 deletions
638
docs/source/Howtos/Web-Character-Generation.md
Normal file
638
docs/source/Howtos/Web-Character-Generation.md
Normal file
|
|
@ -0,0 +1,638 @@
|
|||
# Web Character Generation
|
||||
|
||||
|
||||
## Introduction
|
||||
|
||||
This tutorial will create a simple web-based interface for generating a new in-game Character.
|
||||
Accounts will need to have first logged into the website (with their `AccountDB` account). Once
|
||||
finishing character generation the Character will be created immediately and the Accounts can then
|
||||
log into the game and play immediately (the Character will not require staff approval or anything
|
||||
like that). This guide does not go over how to create an AccountDB on the website with the right
|
||||
permissions to transfer to their web-created characters.
|
||||
|
||||
It is probably most useful to set `MULTISESSION_MODE = 2` or `3` (which gives you a character-
|
||||
selection screen when you log into the game later). Other modes can be used with some adaptation to
|
||||
auto-puppet the new Character.
|
||||
|
||||
You should have some familiarity with how Django sets up its Model Template View framework. You need
|
||||
to understand what is happening in the basic [Web Character View tutorial](Web-Character-View-
|
||||
Tutorial). If you don’t understand the listed tutorial or have a grasp of Django basics, please look
|
||||
at the [Django tutorial](https://docs.djangoproject.com/en/1.8/intro/) to get a taste of what Django
|
||||
does, before throwing Evennia into the mix (Evennia shares its API and attributes with the website
|
||||
interface). This guide will outline the format of the models, views, urls, and html templates
|
||||
needed.
|
||||
|
||||
## Pictures
|
||||
|
||||
Here are some screenshots of the simple app we will be making.
|
||||
|
||||
Index page, with no character application yet done:
|
||||
|
||||
***
|
||||

|
||||
***
|
||||
|
||||
Having clicked the "create" link you get to create your character (here we will only have name and
|
||||
background, you can add whatever is needed to fit your game):
|
||||
|
||||
***
|
||||

|
||||
***
|
||||
|
||||
Back to the index page. Having entered our character application (we called our character "TestApp")
|
||||
you see it listed:
|
||||
|
||||
***
|
||||

|
||||
***
|
||||
|
||||
We can also view an already written character application by clicking on it - this brings us to the
|
||||
*detail* page:
|
||||
|
||||
***
|
||||

|
||||
***
|
||||
|
||||
## Installing an App
|
||||
|
||||
Assuming your game is named "mygame", navigate to your `mygame/` directory, and type:
|
||||
|
||||
evennia startapp chargen
|
||||
|
||||
This will initialize a new Django app we choose to call "chargen". It is directory containing some
|
||||
basic starting things Django needs. You will need to move this directory: for the time being, it is
|
||||
in your `mygame` directory. Better to move it in your `mygame/web` directory, so you have
|
||||
`mygame/web/chargen` in the end.
|
||||
|
||||
Next, navigate to `mygame/server/conf/settings.py` and add or edit the following line to make
|
||||
Evennia (and Django) aware of our new app:
|
||||
|
||||
INSTALLED_APPS += ('web.chargen',)
|
||||
|
||||
After this, we will get into defining our *models* (the description of the database storage),
|
||||
*views* (the server-side website content generators), *urls* (how the web browser finds the pages)
|
||||
and *templates* (how the web page should be structured).
|
||||
|
||||
### Installing - Checkpoint:
|
||||
|
||||
* you should have a folder named `chargen` or whatever you chose in your mygame/web/ directory
|
||||
* you should have your application name added to your INSTALLED_APPS in settings.py
|
||||
|
||||
## Create Models
|
||||
|
||||
Models are created in `mygame/web/chargen/models.py`.
|
||||
|
||||
A [Django database model](../Concepts/New-Models.md) is a Python class that describes the database storage of the
|
||||
data you want to manage. Any data you choose to store is stored in the same database as the game and
|
||||
you have access to all the game's objects here.
|
||||
|
||||
We need to define what a character application actually is. This will differ from game to game so
|
||||
for this tutorial we will define a simple character sheet with the following database fields:
|
||||
|
||||
|
||||
* `app_id` (AutoField): Primary key for this character application sheet.
|
||||
* `char_name` (CharField): The new character's name.
|
||||
* `date_applied` (DateTimeField): Date that this application was received.
|
||||
* `background` (TextField): Character story background.
|
||||
* `account_id` (IntegerField): Which account ID does this application belong to? This is an
|
||||
AccountID from the AccountDB object.
|
||||
* `submitted` (BooleanField): `True`/`False` depending on if the application has been submitted yet.
|
||||
|
||||
> Note: In a full-fledged game, you’d likely want them to be able to select races, skills,
|
||||
attributes and so on.
|
||||
|
||||
Our `models.py` file should look something like this:
|
||||
|
||||
```python
|
||||
# in mygame/web/chargen/models.py
|
||||
|
||||
from django.db import models
|
||||
|
||||
class CharApp(models.Model):
|
||||
app_id = models.AutoField(primary_key=True)
|
||||
char_name = models.CharField(max_length=80, verbose_name='Character Name')
|
||||
date_applied = models.DateTimeField(verbose_name='Date Applied')
|
||||
background = models.TextField(verbose_name='Background')
|
||||
account_id = models.IntegerField(default=1, verbose_name='Account ID')
|
||||
submitted = models.BooleanField(default=False)
|
||||
```
|
||||
|
||||
You should consider how you are going to link your application to your account. For this tutorial,
|
||||
we are using the account_id attribute on our character application model in order to keep track of
|
||||
which characters are owned by which accounts. Since the account id is a primary key in Evennia, it
|
||||
is a good candidate, as you will never have two of the same IDs in Evennia. You can feel free to use
|
||||
anything else, but for the purposes of this guide, we are going to use account ID to join the
|
||||
character applications with the proper account.
|
||||
|
||||
### Model - Checkpoint:
|
||||
|
||||
* you should have filled out `mygame/web/chargen/models.py` with the model class shown above
|
||||
(eventually adding fields matching what you need for your game).
|
||||
|
||||
## Create Views
|
||||
|
||||
*Views* are server-side constructs that make dynamic data available to a web page. We are going to
|
||||
add them to `mygame/web/chargen.views.py`. Each view in our example represents the backbone of a
|
||||
specific web page. We will use three views and three pages here:
|
||||
|
||||
* The index (managing `index.html`). This is what you see when you navigate to
|
||||
`http://yoursite.com/chargen`.
|
||||
* The detail display sheet (manages `detail.html`). A page that passively displays the stats of a
|
||||
given Character.
|
||||
* Character creation sheet (manages `create.html`). This is the main form with fields to fill in.
|
||||
|
||||
### *Index* view
|
||||
|
||||
Let’s get started with the index first.
|
||||
|
||||
We’ll want characters to be able to see their created characters so let’s
|
||||
|
||||
```python
|
||||
# file mygame/web/chargen.views.py
|
||||
|
||||
from .models import CharApp
|
||||
|
||||
def index(request):
|
||||
current_user = request.user # current user logged in
|
||||
p_id = current_user.id # the account id
|
||||
# submitted Characters by this account
|
||||
sub_apps = CharApp.objects.filter(account_id=p_id, submitted=True)
|
||||
context = {'sub_apps': sub_apps}
|
||||
# make the variables in 'context' available to the web page template
|
||||
return render(request, 'chargen/index.html', context)
|
||||
```
|
||||
|
||||
### *Detail* view
|
||||
|
||||
Our detail page will have pertinent character application information our users can see. Since this
|
||||
is a basic demonstration, our detail page will only show two fields:
|
||||
|
||||
* Character name
|
||||
* Character background
|
||||
|
||||
We will use the account ID again just to double-check that whoever tries to check our character page
|
||||
is actually the account who owns the application.
|
||||
|
||||
```python
|
||||
# file mygame/web/chargen.views.py
|
||||
|
||||
def detail(request, app_id):
|
||||
app = CharApp.objects.get(app_id=app_id)
|
||||
name = app.char_name
|
||||
background = app.background
|
||||
submitted = app.submitted
|
||||
p_id = request.user.id
|
||||
context = {'name': name, 'background': background,
|
||||
'p_id': p_id, 'submitted': submitted}
|
||||
return render(request, 'chargen/detail.html', context)
|
||||
```
|
||||
|
||||
## *Creating* view
|
||||
|
||||
Predictably, our *create* function will be the most complicated of the views, as it needs to accept
|
||||
information from the user, validate the information, and send the information to the server. Once
|
||||
the form content is validated will actually create a playable Character.
|
||||
|
||||
The form itself we will define first. In our simple example we are just looking for the Character's
|
||||
name and background. This form we create in `mygame/web/chargen/forms.py`:
|
||||
|
||||
```python
|
||||
# file mygame/web/chargen/forms.py
|
||||
|
||||
from django import forms
|
||||
|
||||
class AppForm(forms.Form):
|
||||
name = forms.CharField(label='Character Name', max_length=80)
|
||||
background = forms.CharField(label='Background')
|
||||
```
|
||||
|
||||
Now we make use of this form in our view.
|
||||
|
||||
```python
|
||||
# file mygame/web/chargen/views.py
|
||||
|
||||
from web.chargen.models import CharApp
|
||||
from web.chargen.forms import AppForm
|
||||
from django.http import HttpResponseRedirect
|
||||
from datetime import datetime
|
||||
from evennia.objects.models import ObjectDB
|
||||
from django.conf import settings
|
||||
from evennia.utils import create
|
||||
|
||||
def creating(request):
|
||||
user = request.user
|
||||
if request.method == 'POST':
|
||||
form = AppForm(request.POST)
|
||||
if form.is_valid():
|
||||
name = form.cleaned_data['name']
|
||||
background = form.cleaned_data['background']
|
||||
applied_date = datetime.now()
|
||||
submitted = True
|
||||
if 'save' in request.POST:
|
||||
submitted = False
|
||||
app = CharApp(char_name=name, background=background,
|
||||
date_applied=applied_date, account_id=user.id,
|
||||
submitted=submitted)
|
||||
app.save()
|
||||
if submitted:
|
||||
# Create the actual character object
|
||||
typeclass = settings.BASE_CHARACTER_TYPECLASS
|
||||
home = ObjectDB.objects.get_id(settings.GUEST_HOME)
|
||||
# turn the permissionhandler to a string
|
||||
perms = str(user.permissions)
|
||||
# create the character
|
||||
char = create.create_object(typeclass=typeclass, key=name,
|
||||
home=home, permissions=perms)
|
||||
user.db._playable_characters.append(char)
|
||||
# add the right locks for the character so the account can
|
||||
# puppet it
|
||||
char.locks.add(" or ".join([
|
||||
f"puppet:id({char.id})",
|
||||
f"pid({user.id})",
|
||||
"perm(Developers)",
|
||||
"pperm(Developers)",
|
||||
]))
|
||||
char.db.background = background # set the character background
|
||||
return HttpResponseRedirect('/chargen')
|
||||
else:
|
||||
form = AppForm()
|
||||
return render(request, 'chargen/create.html', {'form': form})
|
||||
```
|
||||
|
||||
> Note also that we basically create the character using the Evennia API, and we grab the proper
|
||||
permissions from the `AccountDB` object and copy them to the character object. We take the user
|
||||
permissions attribute and turn that list of strings into a string object in order for the
|
||||
create_object function to properly process the permissions.
|
||||
|
||||
Most importantly, the following attributes must be set on the created character object:
|
||||
|
||||
* Evennia [permissions](../Components/Permissions.md) (copied from the `AccountDB`).
|
||||
* The right `puppet` [locks](../Components/Locks.md) so the Account can actually play as this Character later.
|
||||
* The relevant Character [typeclass](../Components/Typeclasses.md)
|
||||
* Character name (key)
|
||||
* The Character's home room location (`#2` by default)
|
||||
|
||||
Other attributes are strictly speaking optional, such as the `background` attribute on our
|
||||
character. It may be a good idea to decompose this function and create a separate _create_character
|
||||
function in order to set up your character object the account owns. But with the Evennia API,
|
||||
setting custom attributes is as easy as doing it in the meat of your Evennia game directory.
|
||||
|
||||
After all of this, our `views.py` file should look like something like this:
|
||||
|
||||
```python
|
||||
# file mygame/web/chargen/views.py
|
||||
|
||||
from django.shortcuts import render
|
||||
from web.chargen.models import CharApp
|
||||
from web.chargen.forms import AppForm
|
||||
from django.http import HttpResponseRedirect
|
||||
from datetime import datetime
|
||||
from evennia.objects.models import ObjectDB
|
||||
from django.conf import settings
|
||||
from evennia.utils import create
|
||||
|
||||
def index(request):
|
||||
current_user = request.user # current user logged in
|
||||
p_id = current_user.id # the account id
|
||||
# submitted apps under this account
|
||||
sub_apps = CharApp.objects.filter(account_id=p_id, submitted=True)
|
||||
context = {'sub_apps': sub_apps}
|
||||
return render(request, 'chargen/index.html', context)
|
||||
|
||||
def detail(request, app_id):
|
||||
app = CharApp.objects.get(app_id=app_id)
|
||||
name = app.char_name
|
||||
background = app.background
|
||||
submitted = app.submitted
|
||||
p_id = request.user.id
|
||||
context = {'name': name, 'background': background,
|
||||
'p_id': p_id, 'submitted': submitted}
|
||||
return render(request, 'chargen/detail.html', context)
|
||||
|
||||
def creating(request):
|
||||
user = request.user
|
||||
if request.method == 'POST':
|
||||
form = AppForm(request.POST)
|
||||
if form.is_valid():
|
||||
name = form.cleaned_data['name']
|
||||
background = form.cleaned_data['background']
|
||||
applied_date = datetime.now()
|
||||
submitted = True
|
||||
if 'save' in request.POST:
|
||||
submitted = False
|
||||
app = CharApp(char_name=name, background=background,
|
||||
date_applied=applied_date, account_id=user.id,
|
||||
submitted=submitted)
|
||||
app.save()
|
||||
if submitted:
|
||||
# Create the actual character object
|
||||
typeclass = settings.BASE_CHARACTER_TYPECLASS
|
||||
home = ObjectDB.objects.get_id(settings.GUEST_HOME)
|
||||
# turn the permissionhandler to a string
|
||||
perms = str(user.permissions)
|
||||
# create the character
|
||||
char = create.create_object(typeclass=typeclass, key=name,
|
||||
home=home, permissions=perms)
|
||||
user.db._playable_characters.append(char)
|
||||
# add the right locks for the character so the account can
|
||||
# puppet it
|
||||
char.locks.add(" or ".join([
|
||||
f"puppet:id({char.id})",
|
||||
f"pid({user.id})",
|
||||
"perm(Developers)",
|
||||
"pperm(Developers)",
|
||||
]))
|
||||
char.db.background = background # set the character background
|
||||
return HttpResponseRedirect('/chargen')
|
||||
else:
|
||||
form = AppForm()
|
||||
return render(request, 'chargen/create.html', {'form': form})
|
||||
```
|
||||
|
||||
### Create Views - Checkpoint:
|
||||
|
||||
* you’ve defined a `views.py` that has an index, detail, and creating functions.
|
||||
* you’ve defined a forms.py with the `AppForm` class needed by the `creating` function of
|
||||
`views.py`.
|
||||
* your `mygame/web/chargen` directory should now have a `views.py` and `forms.py` file
|
||||
|
||||
## Create URLs
|
||||
|
||||
URL patterns helps redirect requests from the web browser to the right views. These patterns are
|
||||
created in `mygame/web/chargen/urls.py`.
|
||||
|
||||
```python
|
||||
# file mygame/web/chargen/urls.py
|
||||
|
||||
from django.urls import path
|
||||
from web.chargen import views
|
||||
|
||||
urlpatterns = [
|
||||
# url: /chargen/
|
||||
path("", views.index, name='chargen-index'),
|
||||
# url: /chargen/5/
|
||||
path("<int:app_id>/", views.detail, name="chargen-detail"),
|
||||
# url: /chargen/create
|
||||
path("create/", views.creating, name='chargen-creating'),
|
||||
]
|
||||
```
|
||||
|
||||
You could change the format as you desire. To make it more secure, you could remove app_id from the
|
||||
"detail" url, and instead just fetch the account’s applications using a unifying field like
|
||||
account_id to find all the character application objects to display.
|
||||
|
||||
To add this to our website, we must also update the main `mygame/website/urls.py` file; this
|
||||
will help tying our new chargen app in with the rest of the website. `urlpatterns` variable, and
|
||||
change it to include:
|
||||
|
||||
```python
|
||||
# in file mygame/website/urls.py
|
||||
|
||||
from django.urls import path, include
|
||||
|
||||
urlpatterns = [
|
||||
# make all chargen endpoints available under /chargen url
|
||||
path("chargen/", include("web.chargen.urls")
|
||||
]
|
||||
|
||||
```
|
||||
|
||||
### URLs - Checkpoint:
|
||||
|
||||
* You’ve created a urls.py file in the `mygame/web/chargen` directory
|
||||
* You have edited the main `mygame/web/urls.py` file to include urls to the `chargen` directory.
|
||||
|
||||
## HTML Templates
|
||||
|
||||
So we have our url patterns, views, and models defined. Now we must define our HTML templates that
|
||||
the actual user will see and interact with. For this tutorial we us the basic *prosimii* template
|
||||
that comes with Evennia.
|
||||
|
||||
Take note that we use `user.is_authenticated` to make sure that the user cannot create a character
|
||||
without logging in.
|
||||
|
||||
These files will all go into the `/mygame/web/chargen/templates/chargen/` directory.
|
||||
|
||||
### index.html
|
||||
|
||||
This HTML template should hold a list of all the applications the account currently has active. For
|
||||
this demonstration, we will only list the applications that the account has submitted. You could
|
||||
easily adjust this to include saved applications, or other types of applications if you have
|
||||
different kinds.
|
||||
|
||||
Please refer back to `views.py` to see where we define the variables these templates make use of.
|
||||
|
||||
```html
|
||||
<!-- file mygame/web/chargen/templates/chargen/index.html-->
|
||||
|
||||
{% extends "base.html" %}
|
||||
{% block content %}
|
||||
{% if user.is_authenticated %}
|
||||
<h1>Character Generation</h1>
|
||||
{% if sub_apps %}
|
||||
<ul>
|
||||
{% for sub_app in sub_apps %}
|
||||
<li><a href="/chargen/{{ sub_app.app_id }}/">{{ sub_app.char_name }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% else %}
|
||||
<p>You haven't submitted any character applications.</p>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<p>Please <a href="{% url 'login'%}">login</a>first.<a/></p>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
```
|
||||
|
||||
### detail.html
|
||||
|
||||
This page should show a detailed character sheet of their application. This will only show their
|
||||
name and character background. You will likely want to extend this to show many more fields for your
|
||||
game. In a full-fledged character generation, you may want to extend the boolean attribute of
|
||||
submitted to allow accounts to save character applications and submit them later.
|
||||
|
||||
```html
|
||||
<!-- file mygame/web/chargen/templates/chargen/detail.html-->
|
||||
|
||||
{% extends "base.html" %}
|
||||
{% block content %}
|
||||
<h1>Character Information</h1>
|
||||
{% if user.is_authenticated %}
|
||||
{% if user.id == p_id %}
|
||||
<h2>{{name}}</h2>
|
||||
<h2>Background</h2>
|
||||
<p>{{background}}</p>
|
||||
<p>Submitted: {{submitted}}</p>
|
||||
{% else %}
|
||||
<p>You didn't submit this character.</p>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<p>You aren't logged in.</p>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
```
|
||||
|
||||
### create.html
|
||||
|
||||
Our create HTML template will use the Django form we defined back in views.py/forms.py to drive the
|
||||
majority of the application process. There will be a form input for every field we defined in
|
||||
forms.py, which is handy. We have used POST as our method because we are sending information to the
|
||||
server that will update the database. As an alternative, GET would be much less secure. You can read
|
||||
up on documentation elsewhere on the web for GET vs. POST.
|
||||
|
||||
```html
|
||||
<!-- file mygame/web/chargen/templates/chargen/create.html-->
|
||||
|
||||
{% extends "base.html" %}
|
||||
{% block content %}
|
||||
<h1>Character Creation</h1>
|
||||
{% if user.is_authenticated %}
|
||||
<form action="/chargen/create/" method="post">
|
||||
{% csrf_token %}
|
||||
{{ form }}
|
||||
<input type="submit" name="submit" value="Submit"/>
|
||||
</form>
|
||||
{% else %}
|
||||
<p>You aren't logged in.</p>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
```
|
||||
|
||||
### Templates - Checkpoint:
|
||||
|
||||
* Create a `index.html`, `detail.html` and `create.html` template in your
|
||||
`mygame/web/chargen/templates/chargen` directory
|
||||
|
||||
## Activating your new character generation
|
||||
|
||||
After finishing this tutorial you should have edited or created the following files:
|
||||
|
||||
```bash
|
||||
mygame/web/website/urls.py
|
||||
mygame/web/chargen/models.py
|
||||
mygame/web/chargen/views.py
|
||||
mygame/web/chargen/urls.py
|
||||
mygame/web/chargen/templates/chargen/index.html
|
||||
mygame/web/chargen/templates/chargen/create.html
|
||||
mygame/web/chargen/templates/chargen/detail.html
|
||||
```
|
||||
|
||||
Once you have all these files stand in your `mygame/`folder and run:
|
||||
|
||||
```bash
|
||||
evennia makemigrations
|
||||
evennia migrate
|
||||
```
|
||||
|
||||
This will create and update the models. If you see any errors at this stage, read the traceback
|
||||
carefully, it should be relatively easy to figure out where the error is.
|
||||
|
||||
Login to the website (you need to have previously registered an Player account with the game to do
|
||||
this). Next you navigate to `http://yourwebsite.com/chargen` (if you are running locally this will
|
||||
be something like `http://localhost:4001/chargen` and you will see your new app in action.
|
||||
|
||||
This should hopefully give you a good starting point in figuring out how you’d like to approach your
|
||||
own web generation. The main difficulties are in setting the appropriate settings on your newly
|
||||
created character object. Thankfully, the Evennia API makes this easy.
|
||||
|
||||
## Adding a no CAPCHA reCAPCHA on your character generation
|
||||
|
||||
As sad as it is, if your server is open to the web, bots might come to visit and take advantage of
|
||||
your open form to create hundreds, thousands, millions of characters if you give them the
|
||||
opportunity. This section shows you how to use the [No CAPCHA
|
||||
reCAPCHA](https://www.google.com/recaptcha/intro/invisible.html) designed by Google. Not only is it
|
||||
easy to use, it is user-friendly... for humans. A simple checkbox to check, except if Google has
|
||||
some suspicion, in which case you will have a more difficult test with an image and the usual text
|
||||
inside. It's worth pointing out that, as long as Google doesn't suspect you of being a robot, this
|
||||
is quite useful, not only for common users, but to screen-reader users, to which reading inside of
|
||||
an image is pretty difficult, if not impossible. And to top it all, it will be so easy to add in
|
||||
your website.
|
||||
|
||||
### Step 1: Obtain a SiteKey and secret from Google
|
||||
|
||||
The first thing is to ask Google for a way to safely authenticate your website to their service. To
|
||||
do it, we need to create a site key and a secret. Go to
|
||||
[https://www.google.com/recaptcha/admin](https://www.google.com/recaptcha/admin) to create such a
|
||||
site key. It's quite easy when you have a Google account.
|
||||
|
||||
When you have created your site key, save it safely. Also copy your secret key as well. You should
|
||||
find both information on the web page. Both would contain a lot of letters and figures.
|
||||
|
||||
### Step 2: installing and configuring the dedicated Django app
|
||||
|
||||
Since Evennia runs on Django, the easiest way to add our CAPCHA and perform the proper check is to
|
||||
install the dedicated Django app. Quite easy:
|
||||
|
||||
pip install django-nocaptcha-recaptcha
|
||||
|
||||
And add it to the installed apps in your settings. In your `mygame/server/conf/settings.py`, you
|
||||
might have something like this:
|
||||
|
||||
```python
|
||||
# ...
|
||||
INSTALLED_APPS += (
|
||||
'web.chargen',
|
||||
'nocaptcha_recaptcha',
|
||||
)
|
||||
```
|
||||
|
||||
Don't close the setting file just yet. We have to add in the site key and secret key. You can add
|
||||
them below:
|
||||
|
||||
```python
|
||||
# NoReCAPCHA site key
|
||||
NORECAPTCHA_SITE_KEY = "PASTE YOUR SITE KEY HERE"
|
||||
# NoReCAPCHA secret key
|
||||
NORECAPTCHA_SECRET_KEY = "PUT YOUR SECRET KEY HERE"
|
||||
```
|
||||
|
||||
### Step 3: Adding the CAPCHA to our form
|
||||
|
||||
Finally we have to add the CAPCHA to our form. It will be pretty easy too. First, open your
|
||||
`web/chargen/forms.py` file. We're going to add a new field, but hopefully, all the hard work has
|
||||
been done for us. Update at your convenience, You might end up with something like this:
|
||||
|
||||
```python
|
||||
from django import forms
|
||||
from nocaptcha_recaptcha.fields import NoReCaptchaField
|
||||
|
||||
class AppForm(forms.Form):
|
||||
name = forms.CharField(label='Character Name', max_length=80)
|
||||
background = forms.CharField(label='Background')
|
||||
captcha = NoReCaptchaField()
|
||||
```
|
||||
|
||||
As you see, we added a line of import (line 2) and a field in our form.
|
||||
|
||||
And lastly, we need to update our HTML file to add in the Google library. You can open
|
||||
`web/chargen/templates/chargen/create.html`. There's only one line to add:
|
||||
|
||||
```html
|
||||
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
|
||||
```
|
||||
|
||||
And you should put it at the bottom of the page. Just before the closing body would be good, but
|
||||
for the time being, the base page doesn't provide a footer block, so we'll put it in the content
|
||||
block. Note that it's not the best place, but it will work. In the end, your
|
||||
`web/chargen/templates/chargen/create.html` file should look like this:
|
||||
|
||||
```html
|
||||
{% extends "base.html" %}
|
||||
{% block content %}
|
||||
<h1>Character Creation</h1>
|
||||
{% if user.is_authenticated %}
|
||||
<form action="/chargen/create/" method="post">
|
||||
{% csrf_token %}
|
||||
{{ form }}
|
||||
<input type="submit" name="submit" value="Submit"/>
|
||||
</form>
|
||||
{% else %}
|
||||
<p>You aren't logged in.</p>
|
||||
{% endif %}
|
||||
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
|
||||
{% endblock %}
|
||||
```
|
||||
|
||||
Reload and open [http://localhost:4001/chargen/create](http://localhost:4001/chargen/create/) and
|
||||
you should see your beautiful CAPCHA just before the "submit" button. Try not to check the checkbox
|
||||
to see what happens. And do the same while checking the checkbox!
|
||||
Loading…
Add table
Add a link
Reference in a new issue