resources

This commit is contained in:
Niko Abeler 2023-06-20 21:22:56 +02:00
parent 451bd333aa
commit d4415445f3
24 changed files with 648 additions and 56 deletions

View File

@ -1,5 +1,6 @@
from django import forms from django import forms
from guild.models import PlaySession, Character from guild.models import PlaySession, Character, Reward
from django.utils.translation import gettext as _
class PlaySessionCharacterForm(forms.ModelMultipleChoiceField): class PlaySessionCharacterForm(forms.ModelMultipleChoiceField):
@ -23,3 +24,15 @@ class PlaySessionForm(forms.ModelForm):
"date": forms.DateInput(attrs={"type": "date"}), "date": forms.DateInput(attrs={"type": "date"}),
"summary": forms.Textarea(attrs={"rows": 32}), "summary": forms.Textarea(attrs={"rows": 32}),
} }
class RewardForm(forms.ModelForm):
character = forms.ModelChoiceField(
queryset=Character.objects.all(),
empty_label="All Guild Members",
required=False,
)
class Meta:
model = Reward
fields = ["amount", "resource", "character"]

View File

@ -0,0 +1,115 @@
# Generated by Django 4.2.1 on 2023-06-20 18:10
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
class Migration(migrations.Migration):
dependencies = [
("guild", "0004_alter_playsession_options_player_address"),
]
operations = [
migrations.AddField(
model_name="adventure",
name="created_at",
field=models.DateTimeField(
auto_now_add=True,
default=django.utils.timezone.now,
verbose_name="created at",
),
preserve_default=False,
),
migrations.AddField(
model_name="adventure",
name="updated_at",
field=models.DateTimeField(auto_now=True, verbose_name="updated at"),
),
migrations.AddField(
model_name="character",
name="created_at",
field=models.DateTimeField(
auto_now_add=True,
default=django.utils.timezone.now,
verbose_name="created at",
),
preserve_default=False,
),
migrations.AddField(
model_name="character",
name="updated_at",
field=models.DateTimeField(auto_now=True, verbose_name="updated at"),
),
migrations.AddField(
model_name="player",
name="created_at",
field=models.DateTimeField(
auto_now_add=True,
default=django.utils.timezone.now,
verbose_name="created at",
),
preserve_default=False,
),
migrations.AddField(
model_name="player",
name="updated_at",
field=models.DateTimeField(auto_now=True, verbose_name="updated at"),
),
migrations.AddField(
model_name="playsession",
name="created_at",
field=models.DateTimeField(
auto_now_add=True,
default=django.utils.timezone.now,
verbose_name="created at",
),
preserve_default=False,
),
migrations.AddField(
model_name="playsession",
name="updated_at",
field=models.DateTimeField(auto_now=True, verbose_name="updated at"),
),
migrations.AddField(
model_name="resource",
name="created_at",
field=models.DateTimeField(
auto_now_add=True,
default=django.utils.timezone.now,
verbose_name="created at",
),
preserve_default=False,
),
migrations.AddField(
model_name="resource",
name="updated_at",
field=models.DateTimeField(auto_now=True, verbose_name="updated at"),
),
migrations.AddField(
model_name="resourceearned",
name="created_at",
field=models.DateTimeField(
auto_now_add=True,
default=django.utils.timezone.now,
verbose_name="created at",
),
preserve_default=False,
),
migrations.AddField(
model_name="resourceearned",
name="updated_at",
field=models.DateTimeField(auto_now=True, verbose_name="updated at"),
),
migrations.AlterField(
model_name="resourceearned",
name="character",
field=models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.SET_NULL,
to="guild.character",
verbose_name="character",
),
),
]

View File

@ -0,0 +1,17 @@
# Generated by Django 4.2.1 on 2023-06-20 18:23
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("guild", "0005_adventure_created_at_adventure_updated_at_and_more"),
]
operations = [
migrations.AlterField(
model_name="resource",
name="name",
field=models.CharField(max_length=255, unique=True),
),
]

View File

@ -0,0 +1,24 @@
# Generated by Django 4.2.1 on 2023-06-20 18:43
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
("guild", "0006_alter_resource_name"),
]
operations = [
migrations.AddField(
model_name="resourceearned",
name="playsession",
field=models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.CASCADE,
to="guild.playsession",
verbose_name="playsession",
),
),
]

View File

@ -0,0 +1,22 @@
# Generated by Django 4.2.1 on 2023-06-20 18:43
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
("guild", "0007_resourceearned_playsession"),
]
operations = [
migrations.AlterField(
model_name="resourceearned",
name="playsession",
field=models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
to="guild.playsession",
verbose_name="playsession",
),
),
]

View File

@ -0,0 +1,20 @@
# Generated by Django 4.2.1 on 2023-06-20 18:48
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
("guild", "0008_alter_resourceearned_playsession"),
]
operations = [
migrations.RenameModel(
old_name="ResourceEarned",
new_name="Reward",
),
migrations.AlterModelOptions(
name="reward",
options={"verbose_name": "reward", "verbose_name_plural": "rewards"},
),
]

View File

@ -8,6 +8,9 @@ class Player(models.Model):
address = models.TextField(_("address"), blank=True) address = models.TextField(_("address"), blank=True)
created_at = models.DateTimeField(_("created at"), auto_now_add=True)
updated_at = models.DateTimeField(_("updated at"), auto_now=True)
class Meta: class Meta:
verbose_name = _("player") verbose_name = _("player")
verbose_name_plural = _("players") verbose_name_plural = _("players")
@ -20,9 +23,12 @@ class Player(models.Model):
class Resource(models.Model): class Resource(models.Model):
name = models.CharField(max_length=255) name = models.CharField(max_length=255, unique=True)
description = models.TextField() description = models.TextField()
created_at = models.DateTimeField(_("created at"), auto_now_add=True)
updated_at = models.DateTimeField(_("updated at"), auto_now=True)
class Meta: class Meta:
verbose_name = _("resource") verbose_name = _("resource")
verbose_name_plural = _("resources") verbose_name_plural = _("resources")
@ -46,6 +52,9 @@ class Adventure(models.Model):
blank=True, blank=True,
) )
created_at = models.DateTimeField(_("created at"), auto_now_add=True)
updated_at = models.DateTimeField(_("updated at"), auto_now=True)
@property @property
def last_session(self): def last_session(self):
return self.playsession_set.order_by("-date").first() return self.playsession_set.order_by("-date").first()
@ -82,6 +91,9 @@ class Character(models.Model):
blank=True, blank=True,
) )
created_at = models.DateTimeField(_("created at"), auto_now_add=True)
updated_at = models.DateTimeField(_("updated at"), auto_now=True)
class Meta: class Meta:
verbose_name = _("character") verbose_name = _("character")
verbose_name_plural = _("characters") verbose_name_plural = _("characters")
@ -102,6 +114,9 @@ class PlaySession(models.Model):
summary = models.TextField() summary = models.TextField()
created_at = models.DateTimeField(_("created at"), auto_now_add=True)
updated_at = models.DateTimeField(_("updated at"), auto_now=True)
class Meta: class Meta:
verbose_name = _("playsession") verbose_name = _("playsession")
verbose_name_plural = _("playsessions") verbose_name_plural = _("playsessions")
@ -118,25 +133,34 @@ class PlaySession(models.Model):
) )
class ResourceEarned(models.Model): class Reward(models.Model):
resource = models.ForeignKey( resource = models.ForeignKey(
"Resource", verbose_name=_("resource"), on_delete=models.CASCADE "Resource", verbose_name=_("resource"), on_delete=models.CASCADE
) )
character = models.ForeignKey( character = models.ForeignKey(
"Character", "Character",
verbose_name=_("character"), verbose_name=_("character"),
on_delete=models.CASCADE, on_delete=models.SET_NULL,
null=True, null=True,
blank=True, blank=True,
) )
playsession = models.ForeignKey(
"PlaySession",
verbose_name=_("playsession"),
on_delete=models.CASCADE,
null=False,
)
amount = models.IntegerField() amount = models.IntegerField()
created_at = models.DateTimeField(_("created at"), auto_now_add=True)
updated_at = models.DateTimeField(_("updated at"), auto_now=True)
class Meta: class Meta:
verbose_name = _("resourceearned") verbose_name = _("reward")
verbose_name_plural = _("resourceearneds") verbose_name_plural = _("rewards")
def __str__(self): def __str__(self):
return self.name return f"{self.resource.name} ({self.amount}) - {self.character}"
def get_absolute_url(self): def get_absolute_url(self):
return reverse("guild:resourceearned_detail", kwargs={"pk": self.pk}) return reverse("guild:reward_detail", kwargs={"pk": self.pk})

View File

@ -42,7 +42,9 @@
{% else %} {% else %}
{% for playsession in adventure.playsession_set.all %} {% for playsession in adventure.playsession_set.all %}
<div class="row section-line"> <div class="row section-line">
<h3 class="column column-75 section-item">{{ playsession.date }}</h3> <a class="column column-75 section-item" href="{% url 'guild:playsession_detail' playsession.id %}">
<h3 class="section-item">{{ playsession.date }}</h3>
</a>
<a class="column button button-outline section-item" href="{% url 'guild:playsession_update' adventure.id playsession.id %}">Edit</a> <a class="column button button-outline section-item" href="{% url 'guild:playsession_update' adventure.id playsession.id %}">Edit</a>
<a class="column button button-clear section-item" href="{% url 'guild:playsession_delete' adventure.id playsession.id %}">Delete</a> <a class="column button button-clear section-item" href="{% url 'guild:playsession_delete' adventure.id playsession.id %}">Delete</a>
</div> </div>
@ -51,7 +53,7 @@
<ul> <ul>
{% for character in playsession.characters.all %} {% for character in playsession.characters.all %}
<li>{{character.name}}</li> <li><a href="{% url 'guild:character_detail' character.id %}">{{ character.name }} ({{character.player.name}})</a></li>
{% endfor %} {% endfor %}
</ul> </ul>

View File

@ -10,10 +10,12 @@
<h1>Character: {{ character.name }}</h1> <h1>Character: {{ character.name }}</h1>
<h4> <h4>
{{ character.get_status_display }} {{ character.get_status_display }}
, played by: {% if character.player %}
<a href="{% url 'guild:player_detail' character.player.id %}"> , played by:
{{ character.player.name }} <a href="{% url 'guild:player_detail' character.player.id %}">
</a> {{ character.player.name }}
</a>
{% endif %}
</h4> </h4>
</hrgroup> </hrgroup>
</div> </div>
@ -42,4 +44,35 @@
</ul> </ul>
{% endif %} {% endif %}
<h2>Rewards</h2>
<ul>
{% for resource, amount in resources.items %}
<li> {{ amount }} {{ resource }} </li>
{% endfor %}
</ul>
<h3>Reward History</h3>
{% if not character.reward_set.count %}
<p>No rewards.</p>
{% else %}
<ul>
{% for reward in rewards %}
<li>
{% if reward.character %}
<strong>
{% endif %}
{{reward.amount}} {{ reward.resource.name }} -
<a href="{% url 'guild:playsession_detail' reward.playsession.id %}">
{{ reward.playsession.date }} - {{ reward.playsession.adventure.name }}
</a>
{% if reward.character %}
</strong>
{% endif %}
</li>
{% endfor %}
</ul>
{% endif %}
{% endblock content %} {% endblock content %}

View File

@ -12,7 +12,6 @@
</div> </div>
</div> </div>
<ul> <ul>
{% for adventure in adventures %} {% for adventure in adventures %}
<li> <li>
@ -28,6 +27,14 @@
{% endfor %} {% endfor %}
</ul> </ul>
<h2>Total Guild Rewards</h2>
<ul>
{% for resource, amount in resources.items %}
<li> {{ amount }} {{ resource }} </li>
{% endfor %}
</ul>
<div class="row"> <div class="row">
<div class="column column-75"> <div class="column column-75">
<h2>Characters</h2> <h2>Characters</h2>

View File

@ -0,0 +1,77 @@
{% extends 'base.html' %}
{% load guild_extras %}
{% block content %}
<div class="row">
<div class="column column-75">
<hrgroup>
<h1>Session: {{ playsession.date }}</h1>
<h4>Adventure:
<a href="{% url 'guild:adventure_detail' playsession.adventure.id %}">
{{ playsession.adventure.name }}
</a>
</h4>
</hrgroup>
</div>
<div class="column">
<a class="button button-outline" href="{% url 'guild:playsession_update' playsession.adventure.id playsession.id %}">Edit</a>
</div>
<div class="column">
<a class="button button-clear" href="{% url 'guild:playsession_delete' playsession.adventure.id playsession.id %}">Delete</a>
</div>
</div>
<hr>
<h3>Characters</h3>
<ul>
{% for character in playsession.characters.all %}
<li><a href="{% url 'guild:character_detail' character.id %}">{{ character.name }} ({{character.player.name}})</a></li>
{% endfor %}
</ul>
<h3>Rewards</h3>
<a href="{% url 'guild:create_reward' playsession.id %}">Add Reward</a>
<table>
<thead>
<tr>
<th>Amount</th>
<th>Resource</th>
<th>Character</th>
<th></th>
</tr>
</thead>
<tbody>
{% for reward in playsession.reward_set.all %}
<tr>
<td>{{ reward.amount }}</td>
<td>{{ reward.resource.name }}</td>
<td>
{% if reward.character %}
<a href="{% url 'guild:character_detail' reward.character.id %}">{{ reward.character.name }}</a>
{% else %}
<em>Every Guild Member</em>
{% endif %}
</td>
<td>
<a href="{% url 'guild:reward_delete' playsession.id reward.id %}">Remove</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% if playsession.reward_set.count == 0 %}
<p>No rewards earned.</p>
{% endif %}
<h3>Summary</h3>
<p>{{playsession.summary|md|safe}}</p>
{% endblock content %}

View File

@ -0,0 +1,16 @@
{% extends 'base.html' %}
{% block content %}
<div class="row">
<div class="column column-75">
<h1>Resource: {{ resource.name }}</h1>
</div>
<div class="column">
<a class="button button-outline" href="{% url 'guild:resource_update' resource.id %}">Edit</a>
</div>
</div>
<p>
{{ resource.description|linebreaks }}
</p>
{% endblock content %}

View File

@ -0,0 +1,13 @@
{% extends 'base.html' %}
{% block content %}
<form action="" method="post">
{% csrf_token %}
{{ form.as_p }}
{% if object %}
<input type="submit" value="Update Resource">
{% else %}
<input type="submit" value="Create Resource">
{% endif %}
</form>
{% endblock content %}

View File

@ -0,0 +1,23 @@
{% extends 'base.html' %}
{% block content %}
<h1>Reward Delete</h1>
<p>Are you sure you want to delete
<strong>
{{ reward.amount }} {{ reward.resource.name }} -
{% if reward.character %}
{{ reward.character.name }}
{% else %}
<em>Every Guild Member</em>
{% endif %}
</strong>?
</p>
<form action="" method="post">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Delete Player">
</form>
{% endblock content %}

View File

@ -0,0 +1,13 @@
{% extends 'base.html' %}
{% block content %}
<form action="" method="post">
{% csrf_token %}
{{ form.as_p }}
{% if object %}
<input type="submit" value="Update Reward">
{% else %}
<input type="submit" value="Create Reward">
{% endif %}
</form>
{% endblock content %}

View File

@ -0,0 +1,26 @@
{% extends 'base.html' %}
{% block content %}
<h1>Settings</h1>
<div class="row">
<div class="column column-75">
<h2>Resources</h2>
</div>
<div class="column column-25">
<a class="button button-outline" href="{% url 'guild:create_resource' %}">Create New Resource</a>
</div>
</div>
<ul>
{% for resource in resources %}
<li>
<a href="{% url 'guild:resource_detail' resource.id %}">
{{ resource.name }}
</a>
</li>
{% endfor %}
</ul>
{% endblock content %}

View File

@ -3,6 +3,9 @@ import guild.views as views
import guild.views.player as player_views import guild.views.player as player_views
import guild.views.character as character_views import guild.views.character as character_views
import guild.views.adventure as adventure_views import guild.views.adventure as adventure_views
import guild.views.playsession as playsession_views
import guild.views.settings as settings_views
import guild.views.resource as resource_views
from django.contrib.auth import views as auth_views from django.contrib.auth import views as auth_views
urlpatterns = [ urlpatterns = [
@ -86,17 +89,52 @@ urlpatterns = [
), ),
path( path(
"adventures/<int:pk>/playsession/create/", "adventures/<int:pk>/playsession/create/",
adventure_views.PlaySessionCreateView.as_view(), playsession_views.PlaySessionCreateView.as_view(),
name="create_playsession", name="create_playsession",
), ),
path( path(
"adventures/<int:pk>/playsession/<int:playsession_pk>/update/", "adventures/<int:pk>/playsession/<int:playsession_pk>/update/",
adventure_views.PlaySessionUpdateView.as_view(), playsession_views.PlaySessionUpdateView.as_view(),
name="playsession_update", name="playsession_update",
), ),
path( path(
"adventures/<int:pk>/playsession/<int:playsession_pk>/delete/", "adventures/<int:pk>/playsession/<int:playsession_pk>/delete/",
adventure_views.PlaySessionDeleteView.as_view(), playsession_views.PlaySessionDeleteView.as_view(),
name="playsession_delete", name="playsession_delete",
), ),
path(
"playsessions/<int:pk>/",
playsession_views.PlaySessionDetailView.as_view(),
name="playsession_detail",
),
path(
"playsessions/<int:pk>/rewards/create/",
playsession_views.CreateRewardView.as_view(),
name="create_reward",
),
path(
"playsessions/<int:pk>/rewards/<int:reward_pk>/delete/",
playsession_views.RewardDeleteView.as_view(),
name="reward_delete",
),
path(
"settings/",
settings_views.SettingsView.as_view(),
name="settings",
),
path(
"resources/create/",
resource_views.CreateResourceView.as_view(),
name="create_resource",
),
path(
"resources/<int:pk>/",
resource_views.ResourceDetailView.as_view(),
name="resource_detail",
),
path(
"resources/<int:pk>/update/",
resource_views.ResourceUpdateView.as_view(),
name="resource_update",
),
] ]

View File

@ -3,7 +3,7 @@ from django.views.generic import TemplateView, ListView, DetailView
from django.views.generic.edit import CreateView from django.views.generic.edit import CreateView
from django.contrib.auth.mixins import LoginRequiredMixin from django.contrib.auth.mixins import LoginRequiredMixin
from guild.models import Adventure, Character, Player from guild.models import Adventure, Character, Player, Reward
# Create your views here. # Create your views here.
@ -21,4 +21,13 @@ class HomeView(LoginRequiredMixin, TemplateView):
context["adventures"] = advs context["adventures"] = advs
context["players"] = Player.objects.all() context["players"] = Player.objects.all()
context["characters"] = Character.objects.all() context["characters"] = Character.objects.all()
context["rewards"] = Reward.objects.filter(character=None).order_by(
"-playsession__date"
)
context["resources"] = {}
for reward in context["rewards"]:
if reward.resource.name not in context["resources"]:
context["resources"][reward.resource.name] = 0
context["resources"][reward.resource.name] += reward.amount
return context return context

View File

@ -39,38 +39,3 @@ class AdventureUpdateView(LoginRequiredMixin, UpdateView):
class AdventureDeleteView(LoginRequiredMixin, DeleteView): class AdventureDeleteView(LoginRequiredMixin, DeleteView):
model = Adventure model = Adventure
success_url = "/" success_url = "/"
class PlaySessionCreateView(LoginRequiredMixin, CreateView):
model = PlaySession
form_class = PlaySessionForm
def dispatch(self, request, *args, **kwargs):
self.adventure = get_object_or_404(Adventure, pk=kwargs["pk"])
return super().dispatch(request, *args, **kwargs)
def form_valid(self, form: BaseModelForm) -> HttpResponse:
form.instance.adventure = self.adventure
return super().form_valid(form)
class PlaySessionUpdateView(LoginRequiredMixin, UpdateView):
model = PlaySession
form_class = PlaySessionForm
pk_url_kwarg = "playsession_pk"
def dispatch(self, request, *args, **kwargs):
self.adventure = get_object_or_404(Adventure, pk=kwargs["pk"])
return super().dispatch(request, *args, **kwargs)
class PlaySessionDeleteView(LoginRequiredMixin, DeleteView):
model = PlaySession
pk_url_kwarg = "playsession_pk"
def dispatch(self, request, *args, **kwargs):
self.adventure = get_object_or_404(Adventure, pk=kwargs["pk"])
return super().dispatch(request, *args, **kwargs)
def get_success_url(self) -> str:
return self.adventure.get_absolute_url()

View File

@ -1,8 +1,8 @@
from django.views.generic import TemplateView, ListView, DetailView from django.views.generic import TemplateView, ListView, DetailView
from django.views.generic.edit import CreateView, UpdateView, DeleteView from django.views.generic.edit import CreateView, UpdateView, DeleteView
from django.contrib.auth.mixins import LoginRequiredMixin from django.contrib.auth.mixins import LoginRequiredMixin
from django.db.models import Q
from guild.models import Character from guild.models import Character, Reward
class CharacterListView(LoginRequiredMixin, ListView): class CharacterListView(LoginRequiredMixin, ListView):
@ -18,6 +18,18 @@ class CreateCharacterView(LoginRequiredMixin, CreateView):
class CharacterDetailView(LoginRequiredMixin, DetailView): class CharacterDetailView(LoginRequiredMixin, DetailView):
model = Character model = Character
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["rewards"] = Reward.objects.filter(
Q(character=self.object) | Q(character=None)
).order_by("-playsession__date")
context["resources"] = {}
for reward in context["rewards"]:
if reward.resource.name not in context["resources"]:
context["resources"][reward.resource.name] = 0
context["resources"][reward.resource.name] += reward.amount
return context
class CharacterUpdateView(LoginRequiredMixin, UpdateView): class CharacterUpdateView(LoginRequiredMixin, UpdateView):
model = Character model = Character

View File

@ -0,0 +1,78 @@
from typing import Any, Dict, Optional, Type
from django.forms.models import BaseModelForm
from django.http import HttpResponse
from django.shortcuts import get_object_or_404
from django.urls import reverse
from django.views.generic import TemplateView, ListView, DetailView
from django.views.generic.edit import CreateView, UpdateView, DeleteView
from django.contrib.auth.mixins import LoginRequiredMixin
from guild.forms import PlaySessionForm, RewardForm
from guild.models import Adventure, PlaySession, Reward
class PlaySessionCreateView(LoginRequiredMixin, CreateView):
model = PlaySession
form_class = PlaySessionForm
def dispatch(self, request, *args, **kwargs):
self.adventure = get_object_or_404(Adventure, pk=kwargs["pk"])
return super().dispatch(request, *args, **kwargs)
def form_valid(self, form: BaseModelForm) -> HttpResponse:
form.instance.adventure = self.adventure
return super().form_valid(form)
class PlaySessionDetailView(LoginRequiredMixin, DetailView):
model = PlaySession
class PlaySessionUpdateView(LoginRequiredMixin, UpdateView):
model = PlaySession
form_class = PlaySessionForm
pk_url_kwarg = "playsession_pk"
def dispatch(self, request, *args, **kwargs):
self.adventure = get_object_or_404(Adventure, pk=kwargs["pk"])
return super().dispatch(request, *args, **kwargs)
class PlaySessionDeleteView(LoginRequiredMixin, DeleteView):
model = PlaySession
pk_url_kwarg = "playsession_pk"
def dispatch(self, request, *args, **kwargs):
self.adventure = get_object_or_404(Adventure, pk=kwargs["pk"])
return super().dispatch(request, *args, **kwargs)
def get_success_url(self) -> str:
return self.adventure.get_absolute_url()
class CreateRewardView(LoginRequiredMixin, CreateView):
model = Reward
form_class = RewardForm
def dispatch(self, request, *args, **kwargs):
self.playsession = get_object_or_404(PlaySession, pk=kwargs["pk"])
return super().dispatch(request, *args, **kwargs)
def form_valid(self, form: BaseModelForm) -> HttpResponse:
form.instance.playsession = self.playsession
return super().form_valid(form)
def get_success_url(self) -> str:
return reverse("guild:playsession_detail", kwargs={"pk": self.playsession.pk})
class RewardDeleteView(LoginRequiredMixin, DeleteView):
model = Reward
pk_url_kwarg = "reward_pk"
def dispatch(self, request, *args, **kwargs):
self.playsession = get_object_or_404(PlaySession, pk=kwargs["pk"])
return super().dispatch(request, *args, **kwargs)
def get_success_url(self) -> str:
return reverse("guild:playsession_detail", kwargs={"pk": self.playsession.pk})

28
guild/views/resource.py Normal file
View File

@ -0,0 +1,28 @@
from django.views.generic import TemplateView, ListView, DetailView
from django.views.generic.edit import CreateView, UpdateView, DeleteView
from django.contrib.auth.mixins import LoginRequiredMixin
from django.urls import reverse
from guild.models import Resource
class CreateResourceView(LoginRequiredMixin, CreateView):
model = Resource
fields = ["name", "description"]
def get_success_url(self):
return reverse("guild:settings")
class ResourceDetailView(LoginRequiredMixin, DetailView):
model = Resource
class ResourceUpdateView(LoginRequiredMixin, UpdateView):
model = Resource
fields = ["name", "description"]
class ResourceDeleteView(LoginRequiredMixin, DeleteView):
model = Resource
success_url = "/"

12
guild/views/settings.py Normal file
View File

@ -0,0 +1,12 @@
from django.views.generic import TemplateView
from guild.models import Resource
class SettingsView(TemplateView):
template_name = "guild/settings.html"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["resources"] = Resource.objects.all()
return context

View File

@ -87,5 +87,10 @@
{% endblock %} {% endblock %}
</main> </main>
<footer class="container">
<hr>
<a href="{% url 'guild:settings' %}">Settings</a>
</footer>
</body> </body>
</html> </html>