Django не может использовать pk для upload_to в сохраненном объекте
Я построил мастера в моем проекте. На первом этапе я создаю объект "Строительство" и сохраняю его в БД. На втором шаге я позволил пользователю загрузить изображение здания, сохраненное на первом шаге.
Изображение в модели здания.
Когда я попытался настроить путь сохранения изображения, я обнаружил, что "instance.pk" - это None.
То же самое происходит, если я пытаюсь получить доступ к каждому атрибуту модели, который должен быть в "экземпляре". Единственные атрибуты, к которым я могу получить доступ, - это те, которые я вручную установил в представлении (например, имя, описание,...)
Я не понимаю, почему это происходит. Может ли кто-нибудь объяснить это мне?
Часть модели:
class Building(models.Model):
utente = models.ForeignKey(User);
nome = models.CharField(max_length=200, unique=True)
descrizione = models.TextField(max_length=1000, blank=True)
link = models.URLField(blank=True)
foto = ImageField(upload_to=content_file_name, blank=True)
...
Content_file_name:
def content_file_name(instance, filename):
estensione = '.jpg'
posizione_punto = filename.rfind('.')
if posizione_punto > 0:
estensione = filename[posizione_punto:]
return '/'.join(['buildings', str(instance.pk), 'vetrina'+estensione])
Часть представления (2-й шаг мастера):
# I load the building from the db
building = get_object_or_404(Building, pk=b_id)
if request.method == 'POST':
form = StepOneForm(request.POST, request.FILES)
if form.is_valid():
data = form.save(commit=False)
building.data_update = datetime.datetime.now()
building.nome = data.nome
building.descrizione = data.descrizione
building.link = data.link
building.foto = data.foto
building.save()
...
1 ответ
Во-первых, вы определили foto
поле как foto = ImageField()
наверное должно быть foto = models.ImageField()
Во-вторых, когда вы запускаете форму, вы не включаете instance
аргумент (взгляните на документы). Это должно быть что-то вроде -
form = StepOneForm(request.POST, request.FILES, instance=building)
Вот как django знает, как добавить данные html-формы в существующий экземпляр. Если вы объявите свою форму, как это -
from django.forms import ModelForm
class BuildingForm(ModelForm):
class Meta:
model = Building
Затем, когда вы делаете data = form.save(commit=False)
ваш data
переменная на самом деле является экземпляром Building
, И если вы уже сказали, что форма относится к конкретному экземпляру (например, building
Вы объявляете в начале своего взгляда), затем data
будет этот конкретный случай Building
,
Это означает, что вы можете изменить свой код просмотра на -
def your_view(request):
building = get_object_or_404(Building, pk=b_id)
if request.method == 'POST':
form = BuildingForm(request.POST, request.FILES, instance=building)
if form.is_valid():
building = form.save(commit=False)
building.save()
else: #...
Ознакомьтесь с документами Form и ModelForm.