Отображение выбора из формы модели, основанной на другой модели
Работаю над проектом, который зашел в тупик, и не могу найти хорошее решение. Обзор проблемы, которую мне нужно решить. У меня есть 3 модели (Games, GameRoles и Groups) У меня есть определенный список игр, и пользователь может создать группу из этого списка. Игры также имеют роли, связанные с ними. Идея заключается в том, что я хочу, чтобы пользователь создавал группу на основе игры из моей модели игры, каждая игра имеет различные роли, связанные с ней. Когда пользователь создает группу, я хочу, чтобы эти роли отображались в поле с флажком, чтобы он мог добавить эти роли, если они ему нужны.
Моя проблема в том, что я не могу найти хороший способ сделать это. Я прочитал документацию и думаю, что мне нужен класс Iterating relationship choice в моем forms.py
Games model.py
from django.db import models
from django.db.models.aggregates import Max
from django.db.models.fields.related import ForeignKey
# Create your models here.
class Game(models.Model) :
GENRE_CHOICES = [
('Action', 'Action'),
('Acion-Adventure', 'Action-Adventure'),
('Adventure', 'Adventure'),
('MMO', 'MMO'),
('Puzzle', 'Puzzle'),
('Role Playing', 'Role Playing'),
('Simulation', 'Simulation'),
('Strategy', 'Strategy'),
('Sports', 'Sports')
]
RATING_CHOICES = [
('E', 'Everyone'),
('E10+', 'Everyone 10+'),
('T', 'Teen'),
('M', 'Mature 17+'),
('A', 'Adults Only 18+'),
('RP', 'Rating Pending')
]
PLATFORM_CHOICES = [
('Multi', 'Multi Platform'),
('PC', 'PC'),
('XBOX', 'XBOX'),
('Playstation', 'Playstation'),
('Nintendo', 'Nintendo')
]
name = models.CharField(max_length=200)
platform = models.CharField(max_length=20,
null=True,
choices=PLATFORM_CHOICES,
default='Select'
)
publisher = models.CharField(max_length=100)
genre = models.CharField(max_length=100,
null=True,
choices=GENRE_CHOICES,
default='Select'
)
rating = models.CharField(max_length=15,
null=True,
choices=RATING_CHOICES,
default='Select'
)
release_date = models.DateField()
tags = models.CharField(max_length=200)
picture = models.ImageField(
max_length=200,
default='games/default.png',
null=True,
upload_to='games/'
)
is_new = models.BooleanField(null=True)
is_popular = models.BooleanField(null=True)
is_featured = models.BooleanField(null=True)
def __str__(self):
return self.name
class GameRole(models.Model):
game = models.ForeignKey(Game, on_delete=models.CASCADE)
role = models.CharField(max_length=200)
def __str__(self):
return self.role
Group models.py
from django.contrib.auth.models import User
from django.db import models
from django.db.models.aggregates import Max
from games.models import Game, GameRole
# Create your models here.
class Group(models.Model):
name = models.CharField(max_length=200)
game = models.ForeignKey(Game, on_delete=models.CASCADE)
size = models.IntegerField(default=1)
total_size = models.IntegerField(null=True)
play_time = models.DateTimeField(null=True)
description = models.TextField(max_length=200)
is_full = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
discord = models.URLField(max_length=200, null=True)
user = models.ForeignKey(User, null=True, on_delete=models.CASCADE)
def __str__(self):
return self.name
class GroupRole(models.Model):
group = models.ForeignKey(Group, on_delete=models.CASCADE)
role = models.ForeignKey(GameRole, on_delete=models.CASCADE)
def __str__(self):
return self.role
forms.py
from django import forms
from django.contrib.auth.models import User
from django.forms import fields, widgets
from LFG.models import Group, GroupMembers, GroupRole
from games.models import Game, GameRole
class DateTimeInput(forms.DateTimeInput):
input_type = 'datetime-local'
class CheckboxInput(forms.CheckboxInput):
input_type = 'checkbox'
class RoleSelect(form.Select):
def creation_option(self, name, value, label, selected, index, subindex=None, attrs=None):
option = super().create_option(name, value, label, selected, index, subindex, attrs)
class GroupForm(forms.ModelForm):
game = forms.ModelChoiceField(queryset=Game.objects.all())
class Meta():
model = Group
fields = ['game', 'name']
class GroupTwoForm(forms.ModelForm):
ROLE_CHOICES = []
roles= forms.ModelMultipleChoiceField(ROLE_CHOICES)
class Meta():
model = Group
fields = ['name', 'total_size', 'play_time', 'description', 'discord']
widgets = {
'play_time':DateTimeInput(),
#'roles':CheckboxInput()
}
def role_display(game_id):
roles = GameRole.object.all()
for role in roles:
if role.game_id == game_id:
r = role
ROLE_CHOICES[r] = r
return ROLE_CHOICES
class GroupMemberForm(forms.ModelForm):
class Meta():
model = GroupMembers
fields = [ 'group', 'member', 'role']
views.py
@login_required(login_url='/login')
def create_group_2_view(request, group_id):
profile = request.user.userprofile
form_user = Group.objects.filter(pk=group_id).values('user')
formID = Group.objects.filter(pk=group_id).first()
roles = GameRole.objects.all()
print(form_user)
if request.method == 'POST':
form = GroupTwoForm(request.POST or None, instance=formID)
# if group_id == form.pk:
if form.is_valid():
form.save()
messages.success(request, 'Group created!')
return redirect('lfg')
else:
print(form.errors)
messages.error(request, form.errors)
return redirect('create-group-2', formID)
else:
form = GroupTwoForm(instance=formID)
context = {
'title':'Create a Group',
'year':datetime.now().year,
'profile':profile,
'form':form,
'roles':roles,
}
return render(request, 'lfg/create-group-2.html', context)
Как вы можете видеть в forms.py, я пытался создать класс секции роли, который будет делать это, а затем передавать его в GroupTwoForm
. Извините, если это немного запутано, я все еще изучаю Django, если потребуется разъяснение, я уточню.