Im trying to create a game tracking app and I wanted the user to be able to see, then update if they wanted, a form that turns on and off features to track. I know this should be quite simple but I cannot for the life of me get the form to populate with the user's data, then be able to update it. Thanks in advance.
views.py
@login_required(login_url='my-login')
def track_pref(request):
user = User.objects.get(username=request.user)
print(user)
if request.method == "POST":
print('first if')
form = UpdateTrackPrefForm(request.user, request.POST)
if form.is_valid():
print('Form Valid')
obj = form.save(commit=False)
obj.user = user
obj.save()
return HttpResponseRedirect('/view-games')
else:
print("else statement")
form = UpdateTrackPrefForm()
context = {'form': form, 'user': user, }
return render(request, 'gametracker_app/track-preference.html', context=context)
forms.py
class UpdateTrackPrefForm(forms.ModelForm):
track_cedh = forms.BooleanField(required=False)
track_wincon = forms.BooleanField(required=False)
track_tournament = forms.BooleanField(required=False)
track_medium = forms.BooleanField(required=False)
class Meta:
model = TrackPref
fields = {'track_cedh',
'track_wincon',
'track_tournament',
'track_medium', }
models.py
class TrackPref(models.Model):
track_cedh = models.BooleanField(default=True)
track_wincon = models.BooleanField(default=True)
track_tournament = models.BooleanField(default=True)
track_medium = models.BooleanField(default=True)
track_note = models.BooleanField(default=True)
user = models.ForeignKey(User,
max_length=100,
on_delete=models.CASCADE,
null=True)
def __str__(self):
return str(self.user)
html
<div class="container shadow-md p-5 form-layout">
<h1 class="">Update Tracking</h1>
<form action=""
method="POST"
autocomplete="off">
{% csrf_token %}
{{ user }}
<br>
{{ form.track_cedh|as_crispy_field }}
{{ form.track_wincon|as_crispy_field }}
{{ form.track_tournament|as_crispy_field }}
{{ form.track_medium|as_crispy_field }}
<br>
<br>
<input class="btn btn-primary"
type="submit"
name=""
value="Submit">
<br>
</form>
</div>
I've tried inserting the user into the view track_pref like below, but I get "argument of type 'User' is not iterable"
@login_required(login_url='my-login')
def track_pref(request):
user = User.objects.get(username=request.user)
print(user)
if request.method == "POST":
print('first if')
form = UpdateTrackPrefForm(request.user, request.POST)
if form.is_valid():
print('Form Valid')
obj = form.save(commit=False)
obj.user = user
obj.save()
return HttpResponseRedirect('/view-games')
else:
print("else statement")
form = UpdateTrackPrefForm(request.user)
While Raphael got me very close, this ended up doing the trick. But, it was a great suggestion to change the model of 'TrackPref' to a OneToOneField.
views.py
@login_required(login_url='my-login')
def track_pref(request):
track_pref = TrackPref.objects.get(user=request.user)
form = UpdateTrackPrefForm(instance=track_pref)
if request.method == "POST":
form = UpdateTrackPrefForm(request.POST, instance=track_pref)
if form.is_valid():
obj = form.save(commit=False)
obj.user = request.user
obj.save()
# I needed to go back to my previous code here
return HttpResponseRedirect('/view-games')
else:
form = UpdateTrackPrefForm(instance=track_pref)
# In this line, the call to get the user's preferences
# needed to be made to see their current preferences.
context = {'form': form, }
return render(request, 'gametracker_app/track-preference.html', context=context)