Замена файла в django - PullRequest
       4

Замена файла в django

0 голосов
/ 10 февраля 2020

У меня есть стандартная форма для редактирования объекта, в котором есть поле файла. Когда я добавляю новый профиль, все работает нормально, но когда я хочу изменить поле, возникают проблемы: когда я не включаю request.FILES, все поля возвращаются в форму и могут быть обновлены без проблем, кроме аватар (файловое поле), но когда я добавляю request.FILES, поля больше не извлекаются во входных данных, и форма недействительна. Что я делаю не так? *

models.py:

from django.db import models

class Profile(models.Model):
    name = models.CharField(max_length=45)
    email = models.EmailField()
    avatar = models.FileField(upload_to="avatars/")

    def __str__(self):
        return self.name

forms.py:

from django import forms
from .models import Profile

class EditUserForm(forms.ModelForm):
    class Meta:
        model = Profile
        fields = ["name", "email", "avatar"]

профиль. html:

<form method="POST">
        {% csrf_token %}
        <div class="col-md-12">
          <div class="row border m-3 p-5">
            <div class="col-md-6">Name</div>
            <div class="col-md-6">{{ form.name }}</div>
          </div>
          <div class="row border m-3 p-5">
            <div class="col-md-6">Email</div>
            <div class="col-md-6">{{ form.email }}</div>
          </div>
          <div class="row border m-3 p-5">
            <div class="col-md-6">Avatar</div>
            <div class="col-md-6">
              <img src="{{ profile.avatar.url }}" width="100rem" />
              {{ form.avatar }}
            </div>
          </div>
          <div class="row">
            <button type="submit" class="btn btn-success">Save</button>
          </div>
        </div>
      </form>

views.py:

def profile(request, pk):
    profile_instance = Profile.objects.get(id=pk)
    form = EditUserForm(request.POST, request.FILES, instance = profile_instance)
    context = {
        'profile': profile_instance,
        'form': form,
    }
    if request.method == "POST":
        if form.is_valid():
            profile = form.save(commit=False)
            profile.save()
        else:
            print("form not valid")
    else:
        return render(request, "app/profile.html", context)

    return render(request, "app/profile.html", context)

Ответы [ 2 ]

0 голосов
/ 10 февраля 2020

Особая благодарность @bruno desthuilliers и @dirkgroten. Вот ответ для решения 2 задач:

def profile(request, pk):
    if request.method == 'POST':
        form = EditUserForm(request.POST, request.FILES, instance = Profile.objects.get(id=pk))
        if form.is_valid():
            profile = form.save(commit=False)
            profile.save()
            return redirect('profile', pk)
    else:
        form = EditUserForm(instance = Profile.objects.get(id=pk))
    context = {
        'profile': Profile.objects.get(id=pk),
        'form': form,
    }
    return render(request, "app/profile.html", context)
0 голосов
/ 10 февраля 2020

Попробуйте выполнить рефакторинг кода следующим образом: (отредактируйте его, если я что-то пропустил. После form.is_valid, такая же форма должна быть отправлена ​​в контексте для отображения ошибок.

def profile(request, pk):
    profile_instance = Profile.objects.get(id=pk)
    form = EditUserForm(instance = profile_instance)
    if request.method == "POST":
        form = EditUserForm(request.POST, request.FILES, instance = profile_instance)
        if form.is_valid():
            profile = form.save(commit=False)
            profile.save()
            form = EditUserForm(instance = profile_instance)

   context = {
        'profile': profile_instance,
        'form': form,
    }

    return render(request, "app/profile.html", context)
...