Within my Django application, I have two models:
Event
and Game
The Event
model has a ForeignKey to the Game
model.
I have a page that lists all the games using a {% for game in game_list %}
, and I'm trying to create a button that will take me to the Events Form to allow me to add an event to the game.
The event form only has 3 fields. project
, event_name
and event_date
. When you land on the event form page I'd like to have the project name populated with the game name from the previous page.
But when I create the link to form my page breaks. Im using:
<a href="{% url 'add-event' game.id %}">Add Key Event</a>
to take to the event form.
Models
class Event(models.Model):
project = models.ForeignKey(Game, to_field='project_name', on_delete=models.CASCADE)
event_name = models.CharField(max_length=20)
event_date = models.DateTimeField(blank=True, null=True)
def __str__(self):
return str(self.event_name)
class Game(models.Model):
project_name = models.CharField(max_length=255, blank=False, unique=True)
project_website = models.URLField(max_length=255, blank=True)
project_description = models.TextField(blank=True)
def __str__(self):
return str(self.project_name)
View
def add_event(request,game_id):
event = Event.objects.get(pk=game_id)
form = addEventForm(request.POST or None, instance=event)
return render(request, 'pages/add_event.html', {'event': event, "form" : form})
URL
path('add_event/<game_id>', view=add_event, name="add-event"),
Error
DoesNotExist at /apps/add_event/13
Event matching query does not exist.
Request Method: GET
Request URL: http://127.0.0.1:8000/apps/add_event/13
Django Version: 3.2.8
Exception Type: DoesNotExist
Exception Value:
Event matching query does not exist.
I think the issue is with this line
event = Event.objects.get(pk=game_id)
But I'm not sure how what is wrong, other than maybe the view is expecting something else other than the game_id
So I changed the plan and thought I'd just go with a dropdown list that allowed me to select the game to assign the event to. BUT the drop-down is showing the duplicated game.project_names, I think because in the database the project_name has multiple events. How do I get the dropdown to only show once for each project_name?
<select class="form-control" name="choices-single-no-sorting" id="project-tier-entry-level">
{% for project in event.game.project_name %}
<option value="" disabled selected hidden>Please Choose...</option>
<option>{{ project }}</option>
{% endfor %}
</select>
CodePudding user response:
I think you should review your view something like this, if its only to create an event:
def add_event(request):
form = addEventForm(request.POST or None)
if request.method == 'POST'
if event_form.is_valid():
event = event_form.save()
return render(request, 'pages/add_event.html', {'event': event, "form" : form})
You can improve it to manage also event's updates:
def manage_event(request, event_id=0):
if event_id == 0:
# Create a new event: there is no instance yet of the event
form = addEventForm(request.POST or None)
else:
# Update an existing event, you can instantiate it
form = addEventForm(request.POST or None, instance=event)
if request.method == 'POST'
# You are posting either a creation or an update
if event_form.is_valid():
# If you need to add control before saving, you need to distinguish both like for the form creation
event = event_form.save()
return render(request, 'pages/add_event.html', {'event': event, "form" : form})
CodePudding user response:
Maybe the game_id is actually a string, so try converting it to an integer first. In other words, change it to
event = Event.objects.get(pk=int(game_id))
or
path('add_event/<int:game_id>', view=add_event, name="add-event")
or both.
Try changing
<select class="form-control" name="choices-single-no-sorting" id="project-tier-entry-level">
{% for project in event.game.project_name %}
<option value="" disabled selected hidden>Please Choose...</option>
<option>{{ project }}</option>
{% endfor %}
to:
<select class="form-control" name="choices-single-no-sorting" id="project-tier-entry-level">
<option value="" disabled selected hidden>Please Choose...</option>
{% for project in event.game.project_name %}
<option>{{ project }}</option>
{% endfor %}
</select>
The 'Please choose' option should not be in the loop.