djangodjango-modelsdjango-viewsdjango-forms

Django: Allowing a User being able to see, then update, form of their information


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)

Solution

  • 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)