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

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

view.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)

формы.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', }

модели.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, как показано ниже, но получаю сообщение «аргумент типа «Пользователь» не повторяется»

@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)
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
56
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

# views.py

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

    track_pref = TrackPref.objects.get(user=request.user)
    form = UpdateTrackPrefForm(instance=track_pref)

    if request.method == "POST":
        print('first if')
        form = UpdateTrackPrefForm(request.POST, instance=track_pref)    # NOTE THE CHANGE HERE
        if form.is_valid():
            print('Form Valid')
            form.save(commit=False)
            return HttpResponseRedirect('/view-games')
    else:
        print("else statement")
        # or, to troubleshoot,
        print((form.errors)
        # THIS IS NOT NEEDED
        # form = UpdateTrackPrefForm()

    context = {'form': form, 'user': user, }
    return render(request, 'gametracker_app/track-preference.html', context=context)

Установка instance=track_pref должна получить обновляемый TrackPref вместо создания нового экземпляра.

Кроме того, я не уверен, что ForeignKey — это то, что вам нужно, поскольку я думаю, что каждый TrackPref связан только с одним User, а ForeignKey — это ManyToOne отношение. Возможно, лучше использовать OneToOneField:

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

    # NOTE THE CHANGE HERE
    user = models.OneToOneField(User,
                                max_length=100,
                                on_delete=models.CASCADE,
                                null=True)

    def __str__(self):
        return str(self.user)

Редактировать
На самом деле вам даже не нужен оператор else, кроме как для того, чтобы вызвать ошибку, или сообщить пользователю о наличии ошибки, или просто распечатать ошибки для себя для устранения неполадок. Моя ошибка заключалась в том, что я вообще не рассматривал оператор else, который не нужен, за исключением того, что я только что объяснил.

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

bld-sync 29.05.2024 23:34

Я обновил ответ @bld-sync, чтобы выполнить обновление формы вместо создания нового экземпляра в базе данных. Надеюсь, это сработает так, как вы задумали.

raphael 30.05.2024 07:42

Мне жаль, что этот ответ так запоздал. Проблемы ИРЛ. Но это не помогло. Он не только не показывает текущие настройки пользователя, но и не обновляет экземпляр предпочтений при отправке формы.

bld-sync 05.06.2024 23:05

Да, @bld-sync, ты прав. Я пренебрег изменением оператора else, который, как я объясняю, хорошо иметь в своем редактировании и в отредактированном коде, но в этом нет необходимости. Но я рад, что у вас все получилось так, как вы хотели, и рад, что помог.

raphael 06.06.2024 00:41
Ответ принят как подходящий

Хотя Рафаэль подвел меня очень близко, в конечном итоге это сработало. Но это было отличное предложение изменить модель TrackPref на OneToOneField.

view.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)

Другие вопросы по теме