Django: Предоставление пользователю возможности просматривать, а затем обновлять информацию о себе

Я пытаюсь создать приложение для отслеживания игр и хочу, чтобы пользователь мог видеть, а затем обновлять, если захочет, форму, которая включает и выключает функции для отслеживания. Я знаю, что это должно быть довольно просто, но я не могу заставить форму заполняться данными пользователя, а затем обновлять их. Заранее спасибо.

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>

Я пробовал вставить пользователя в представление track_pref, как показано ниже, но получаю "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)

Дело в том, как вы пытаетесь включить пользователя в форму, которая не ожидает двух аргументов (form = UpdateTrackPrefForm(request.user, request.POST)), а также в том, как вы пытаетесь получить User, возможно, проблема в этом (user = User.objects.get(username=request.user)). request.user - это User, а username - нет. Попробуйте следующее:

@login_required(login_url='my-login')
def track_pref(request):

    # The following are not needed, but the first is incorrect anyway
    # user = User.objects.get(username=request.user)
    # print(user)

    if request.method == "POST":
        print('first if')
        form = UpdateTrackPrefForm(request.POST)    # NOTE THE CHANGE HERE
        if form.is_valid():
            print('Form Valid')
            obj = form.save(commit=False)
            obj.user = request.user    # NOTE THE CHANGE HERE
            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)

Хотя Рафаэль очень близко подвел меня к этому, в итоге все получилось. Но это было отличное предложение - изменить модель 'TrackPref' на 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)

Вернуться на верх