我在一个网站上工作,在那里你可以上传一个项目。每个项目都包含一个名称,描述,图像和截止日期,您可以设置。
当我试图通过按下“保存项目”按钮上传项目时,我会按预期重定向到我的主页,但图像不会被保存,其他所有内容都会保存。我没有收到任何错误信息。
models.py:
from django.db import models
class Project(models.Model):
project_name = models.CharField(max_length=100)
project_description = models.CharField(max_length=2000)
created_at = models.DateTimeField(auto_now_add=True, null=True, blank=True,)
deadline = models.DateTimeField(null=True, blank=True)
def __str__(self):
return self.project_name
class Image(models.Model):
project = models.ForeignKey(Project, on_delete=models.CASCADE, related_name='project_images')
image = models.ImageField(null=True, blank=True, upload_to="images/")
def __str__(self):
return self.image.name
forms.py:
from django import forms
from django.forms import inlineformset_factory
from .models import Project, Image
class ProjectForm(forms.ModelForm):
class Meta:
model = Project
fields = ['project_name', 'project_description', 'deadline']
widgets = {
'deadline': forms.DateTimeInput(attrs={'type': 'date'}),
}
ImageFormSet = inlineformset_factory(Project, Image, fields=('image',), extra=5, can_delete=True,)
views.py:
from django.shortcuts import render, redirect, get_object_or_404
from .models import Project
from .forms import ProjectForm, ImageFormSet
def homepage(request):
projects = Project.objects.all()
context = {
'projects': projects,
}
return render(request, 'project.html', context)
def create_project(request):
if request.method == 'POST':
project_form = ProjectForm(request.POST)
if project_form.is_valid():
project = project_form.save()
formset = ImageFormSet(request.POST, request.FILES, instance=project)
if formset.is_valid():
formset.save()
return redirect('http://127.0.0.1:8000')
else:
project_form = ProjectForm()
formset = ImageFormSet()
context = {
'project_form': project_form,
'formset': formset,
}
return render(request, 'create_project.html', context)
create_project.html:
<!DOCTYPE html>
<html>
<head>
<title>Create Project</title>
</head>
<body>
<h1>Create Project</h1>
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
<label for="{{ project_form.project_name.id_for_label }}">Project name:</label>
{{ project_form.project_name }}
<br>
<label for="{{ project_form.project_description.id_for_label }}">Project description:</label>
{{ project_form.project_description }}
<br>
{{ formset.management_form }}
<div id="image-container"></div>
<br>
<label for="{{ project_form.deadline.id_for_label }}">Deadline:</label>
{{ project_form.deadline }}
<br>
<button type="button" id="add-image-btn">Add Image</button>
<button type="submit">Save Project</button>
</form>
<script>
document.addEventListener('DOMContentLoaded', () => {
const addImageBtn = document.getElementById('add-image-btn');
const imageContainer = document.getElementById('image-container');
let imageCount = 0;
addImageBtn.addEventListener('click', () => {
// Checks if imagefield is empty
const previousImageInput = document.querySelector(`[name="form-${imageCount-1}-image"]`);
if (previousImageInput && previousImageInput.value === '') {
alert('Add a image to the existing field, before creating a new one.');
return;
}
if (imageCount < 5) {
const newImageRow = document.createElement('div');
newImageRow.className = 'image-row';
const label = document.createElement('label');
label.textContent = 'Image:';
const imageInput = document.createElement('input');
imageInput.type = 'file';
imageInput.name = `form-${imageCount}-image`;
const deleteBtn = document.createElement('button');
deleteBtn.type = 'button';
deleteBtn.className = 'delete-image-btn';
deleteBtn.textContent = 'Delete Image';
newImageRow.appendChild(label);
newImageRow.appendChild(imageInput);
newImageRow.appendChild(deleteBtn);
imageContainer.appendChild(newImageRow);
imageCount++;
}
});
imageContainer.addEventListener('click', (event) => {
if (event.target.className === 'delete-image-btn') {
const imageRow = event.target.parentNode;
imageRow.remove();
imageCount--;
}
});
});
</script>
</body>
</html>
project.html:
<!DOCTYPE html>
<html>
<head>
<title>Create Projects</title>
</head>
<body>
<a href="/create_project"><h2>Create a new project</h2></a>
<h1>Projects</h1>
{% for project in projects|dictsortreversed:"created_at" %}
<div>
<hr>
<h2>{{ project.project_name }}</h2>
<p>{{ project.project_description }}</p>
<p>Created at: {{ project.created_at }}</p>
{% if project.deadline %}
<p>Deadline: {{ project.deadline }}</p>
{% endif %}
{% for image in project.project_images.all %}
{% if image.image %}
<img src="{{ image.image.url }}" alt="Project Picture could not be loaded" style="max-width: 500px;">
{% else %}
<p>No image available for this project.</p>
{% endif %}
{% empty %}
<p>No images available for this project.</p>
{% endfor %}
<a href="{% url 'edit_project' project.id %}">Bearbeiten</a>
<br>
</div>
{% empty %}
<p>Keine Projekte vorhanden.</p>
{% endfor %}
</body>
</html>
settings.py:
STATIC_URL = 'static/'
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'static'),
)
urls.py:
from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('projekte.urls')),
]+static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
urls.py:
from django.urls import path
from . import views
urlpatterns = [
path('', views.homepage, name='index'),
path('delete_picture/<int:project_id>/', views.delete_picture, name='delete_picture'),
path('edit_project/<int:project_id>/', views.edit_project, name='edit_project'),
path('delete_project/<int:project_id>/', views.delete_project, name='delete_project'),
path('create_project', views.create_project, name='create_project'),
]
在模型中,我定义了两个模型,Project和Image。“项目”处理项目名称,描述,创建日期和截止日期。“Image”包含一个Imagefield,并且与Project有外键关系。
Forms有一个使用Modelform的名为Projectform的类。我把它和模型项目联系起来了。之后,我使用inlineformset_factory为Project和Image模型创建了一个内联表单集工厂,因此它可以为一个项目处理许多图像。
有两个功能。其中之一是homepage,它从数据库中检索所有项目,并将其传递给project.html。它会显示所有信息,比如名字,图像...第二个函数“create_project”处理用于创建新项目的GET和POST请求。当发出POST请求时,它验证ProjectForm和关联的ImageFormSet。如果这两个表单都有效,它应该保存项目和相关的图像,然后重定向到主页。当发出GET请求时,它将创建ProjectForm和ImageFormSet的示例,以显示用于创建新项目的空表单。表单作为上下文数据传递给create_project.html模板进行呈现。
Create_project. html是用于创建项目的基本HTML模板。它包括一个表单,其中包含项目名称、描述、截止日期等字段,以及添加多个图像的选项。表单使用POST方法和enctype multipart/form-data来处理文件上传。
底部的脚本部分包含代码,当单击“添加图像”按钮时,该代码检查前一个图像输入字段是否为空。如果是,则显示警告,并且不创建新的图像字段。这样可以确保用户在添加新图像字段之前先填写上一个图像字段。
- 如果前一图像输入字段不为空并且总图像计数小于5,则创建新图像字段。每个图像字段由一个标签、一个“文件”类型的输入字段和一个删除按钮组成。“添加图像”按钮还创建了一个“删除图像”按钮。它从DOM中删除相应的图像字段并减少图像计数。
这至少是我尝试过的,但它不会保存图像,也不会保存到数据库中。只是一个猜测,但我认为问题可能在于create_project.html文件,因为它已经能够保存多个图像,但经过一些变化,并添加一个它打破了,我无法修复它。我的目标是当我按下“保存项目”,也图像得到保存不仅名称,描述,截止日期,创建日期。
输入表单截图:
保存项目后主页截图:
感谢您的关注:)
1条答案
按热度按时间du7egjpx1#
通过引用
.save
方法中的项目当fileForm作为modelForm使用时,它可以工作,无论如何,为什么你不把imagefield放在项目模型上?