Ok I´ve added it
def create_project_new(request):
form = ProjectForm()
profile = request.user.profile
if request.method == 'POST':
form = ProjectForm(request.POST)
images = request.FILES.getlist('image')
if form.is_valid():
project = form.save(commit=False)
project.owner = profile
for i in images:
ProjectImage.objects.create(project=project_instance, image=i)
project.save()
context = {'form':form}
return render(request, 'projects/project_form.html', context)
Ok if I got all things right, this should be the working version
def create_project_new(request):
form = ProjectForm()
profile = request.user.profile
if request.method == 'POST':
form = ProjectForm(request.POST)
images = request.FILES.getlist('image')
if form.is_valid():
project = form.save(commit=False)
project.owner = profile
project.save()
for i in images:
ProjectImage.objects.create(project=project, image=i)
context = {'form':form}
return render(request, 'projects/project_form.html', context)
1 Like
Thanks then I would adjust my update and delete view like this right?
views.py
def update_project(request, pk):
profile = request.user.profile
project = profile.project_set.get(id=pk)
form = ProjectForm(instance=project)
if request.method == 'POST':
form = ProjectForm(request.POST, instance=project)
images = request.FILES.getlist('image')
if form.is_valid():
form.save()
for i in images:
ProjectImage.objects.update_or_create(project=project, image=i)
return redirect('projects')
context = {'form':form}
return render(request, 'projects/project_form.html', context)
def deleteProject(request, pk):
profile = request.user.profile
project = profile.project_set.get(id=pk)
if request.method == "POST":
for i in images:
ProjectImage.objects.update_or_create(project=project, image=i)
project.delete()
return redirect('account')
context = {'object':project}
return render(request, 'delete_template.html', context)
Update and delete operations are going to be different.
If you want to update or remove individual files associated with a project, you’ll probably want to use a formset (or more likely a ModelFormset) to assign an individual file to an individual form.
Keep in mind that changing or deleting a FileField object does not affect the file physically stored on the file system. This means your process to update the individual ProjectImage instances needs to identify when an individual instance has been changed, and remove the original file in addition to storing the new file.
Likewise, when a project is being deleted, you will need to go through all the ProjectImage instances and delete the files before deleting the Project instance.
Ok I think I never worked with formsets before but will try my best.
views.py:
from django.forms import modelformset_factory
def update_project(request, pk):
profile = request.user.profile
ProjectFormSet = modelformset_factory(Project, fields='title', 'describtion', 'price')
form = ProjectFormSet(queryset=Project.object.get(id=pk))
if request.method == 'POST':
form = ProjectFormSet(request.POST, instance=project)
images = request.FILES.getlist('image')
if form.is_valid():
form.save(comit=False)
for i in images:
ProjectImage.objects.update_or_create(project=project, image=i)
return redirect('projects')
context = {'form':form}
return render(request, 'projects/project_form.html', context)
I found this: can_delete=True
in the docs. Do I have to add this in my create_project_new
. Or in other words. Can I create the ``delete_project```view without this parameter?
The only can_delete
parameter I’m aware of is a formset parameter, which sets a flag indicating that each form in the formset could be flagged for deletion. It affects the UI, it has no effect on the underlying model.
You wouldn’t use it at all in create_project_new
because as of the last version I have seen, you’re not using a formset there.
You don’t need it in your delete_project
view, because if you’re deleting a project, you will be deleting all the images along with it.
You may want to use it in your update_project
view, if you want to give the user the ability to delete individual images.
Ok thanks I just added it to my update_project
for now. Could give me feedback to this one?
from django.forms import modelformset_factory
def update_project(request, pk):
profile = request.user.profile
ProjectFormSet = modelformset_factory(Project, can_delete=True, fields='title', 'describtion', 'price')
form = ProjectFormSet(queryset=Project.object.get(id=pk))
if request.method == 'POST':
form = ProjectFormSet(request.POST, instance=project)
images = request.FILES.getlist('image')
if form.is_valid():
form.save(comit=False)
for i in images:
ProjectImage.objects.update_or_create(project=project, image=i)
return redirect('projects')
context = {'form':form}
return render(request, 'projects/project_form.html', context)
Some general thoughts, but with a caveat - I’ve never used a formset with an ImageField, so I don’t know if there are more issues than what I can see here.
First, it appears that this method is only allowing for the editing of the images. It doesn’t provide any facility for updating the Project object.
Also, read the complete section of the docs regarding can_delete
, paying particular attention to the section that discusses the use of the commit=False
parameter in the form.save()
call.
Finally, keep in mind what I mentioned earlier regarding file fields. Deleting an object with a FileField does not delete the physical file in the file system. If you want the image files to be deleted along with the model instance, you need to do that yourself.
For now I would just do not add can_delete=True
To really delete the file I would add something like this:
if instance.images:
if os.path.isfile(instance. images.path):
os.remove(instance.images.path)
Could you give me an overview on how I can really update the Project object
Your view would render a model form for Project with the fields you want to allow to have updated, and then you would include the formset as an additional field in the form.