uploading multiple files in django form and function in views - django

I am trying to upload multiple files in Django form. I followed multiple methods. I am successful via models to views but I want via models to forms to views. I followed Use view/form in Django to upload a multiple files this question but my form is not submitting. Here I am sharing my codes. I hope to get the mistake I am doing by any expert.
#models.py
class Question(models.Model):
description = models.TextField(blank=True, null=True)
created_by = models.ForeignKey(User, blank=False, on_delete=models.CASCADE)
def __str__(self):
return self.description
class QuestionFile(models.Model):
question = models.ForeignKey(
Question, on_delete=models.CASCADE, related_name='files', null=True, blank=True)
file = models.FileField(
'files', upload_to=path_and_rename, max_length=500, null=True, blank=True)
def __str__(self):
return str(self.question)
#forms.py
from django import forms
from .models import *
class QuestionForm(forms.ModelForm):
class Meta:
model = Question
fields = ['description']
class QuestionFileForm(QuestionForm): # extending Questionform
file = forms.FileField(
widget=forms.ClearableFileInput(attrs={'multiple': True}))
class Meta(QuestionForm.Meta):
fields = QuestionForm.Meta.fields + ['file', ]
def clean(self):
cleaned_data = super().clean()
description = cleaned_data.get("description")
file = cleaned_data.get("file")
if not description and not file:
self.add_error(
'description', 'Kindly describe the question details or upload any file')
#views.py
def questionView(request):
if request.method == 'POST':
form = QuestionFileForm(request.POST or None, request.FILES or None)
files = request.FILES.getlist('file')
if form.is_valid():
question = form.save(commit=False)
question.created_by = request.user
# add everything needed to add here
question.save()
if files: # check if user has uploaded some files
for file in files:
QuestionFile.objects.create(question=question, file=file)
messages.success(request, 'Question asked successfully.')
return redirect('url_name')
else:
form = QuestionFileForm()
context = {
"page_title": "Ask a Math Question",
"form": form
}
return render(request, 'template.html', context)
#template.html
{% extends 'base.html' %}
<!-- title -->
{% block title %}{{ page_title }}{% endblock title %}
<!-- body -->
{% block content %}
<div class="ask_question text-center">
<!--for message-->
{% if messages %} {% for message in messages %}
<div
{% if message.tags %}
class="alert alert-{{ message.tags }} text-center"
{% endif %}
>
{{ message }}
</div>
{% endfor %} {% endif %}
<form
method="POST"
action="{% url 'fask_question' %}"
novalidate
class="needs-validation"
enctype="multipart/form-data"
>
{% csrf_token %}
<div class="mb-3">
<input
type="file"
class="clearablefileinput form-control-file"
name="files"
id="exampleFormControlFile1"
multiple
/>
</div>
<div class="mb-3">
<textarea
class="form-control"
id="exampleFormControlTextarea1"
rows="8"
placeholder="Type your question here"
name="description"
></textarea>
</div>
<button type="submit" class="btn">Submit</button>
</form>
</div>
{% endblock %}
I am unable to understand where I am making the mistake that my form is not submitting.
If anyone can help I will be grateful.
Thanks in advance.

Try to pass the form from the context in to the template
Change this part of your template
<form
method="POST"
action="{% url 'fask_question' %}"
novalidate
class="needs-validation"
enctype="multipart/form-data"
>
{% csrf_token %}
<div class="mb-3">
<input
type="file"
class="clearablefileinput form-control-file"
name="files"
id="exampleFormControlFile1"
multiple
/>
</div>
<div class="mb-3">
<textarea
class="form-control"
id="exampleFormControlTextarea1"
rows="8"
placeholder="Type your question here"
name="description"
></textarea>
</div>
<button type="submit" class="btn">Submit</button>
</form>
To
<form
method="POST"
action="{% url 'fask_question' %}"
novalidate
class="needs-validation"
enctype="multipart/form-data"
>
{% csrf_token %}
{{ form }}
<button type="submit" class="btn">Submit</button>
</form>

Related

Django reference multiple image in template

Hi I am letting the user upload multiple images per project but so far the images are not displayed. In projects.html all projects should be displayed and the title and the describtion work so far. But the main-image doesn´t show up. In single-project all images should be displayed.
What do I have to change in my models.py?
Thanks in forward
models.py
class Project(models.Model):
title = models.CharField(max_length=200)
describtion = models.TextField(null=True, blank=True)
id = models.UUIDField(default=uuid.uuid4, unique=True, primary_key=True, editable=False)
class ProjectImage(models.Model):
project = models.ForeignKey(Project, on_delete=models.CASCADE)
featured_images = models.FileField()
forms.py
class ProjectForm(ModelForm):
featured_images = forms.ImageField(widget=ClearableFileInput(attrs={'multiple':True}))
class Meta:
model = Project
fields = ['title', 'describtion', 'featured_images']
views.py
def createProject(request):
form = ProjectForm()
if request.method == 'POST':
form = ProjectForm(request.POST)
images = request.FILES.getlist('image')
if form.is_valid():
project = form.save()
for i in images:
ProjectImage(project=project, image=i).save()
context = {'form':form}
return render(request, 'projects/project_form.html', context)
def projects(request):
projects = Project.objects.all()
context = {"projects":projects}
return render(request, 'projects/projects.html', context)
def project(request, pk):
projectObj = Project.objects.get(id=pk)
return render(request, 'projects/single-project.html', {'project':projectObj})
projects.html
{% for project in projects %}
<div class="column">
<div class="card project">
<a href="{% url 'project' project.id %}" class="project">
<img class="project__thumbnail" src="{{project.featured_images.url}}" alt="project thumbnail" />
<div class="card__body">
<h3 class="project__title">{{project.title}}</h3>
<h3 class="project__title">{{project.price}} €</h3>
</div>
</a>
</div>
</div>
{% endfor %}
single-project.html
<h3 class="project__title">{{project.title}}</h3>
<h3 class="project__title">{{project.price}} €</h3>
<h3 class="singleProject__subtitle">Infos zum Produkt</h3>
{{project.describtion}}
project_form.html
<form class="form" method="POST" enctype="multipart/form-data">
{% csrf_token %}
{% for field in form %}
<div class="form__field">
<label for="formInput#text">{{field.label}}</label>
{{field}}
</div>
{% endfor %}
<input class="btn btn--sub btn--lg my-md" type="submit" value="Submit" />
</form>
To access the images of a project, you need to use the related manager in your templates:
projects.html
{% for project in projects %}
<div class="column">
<div class="card project">
<a href="{% url 'project' project.id %}" class="project">
<img class="project__thumbnail" src="{{project.projectimage_set.all.0.featured_images.url}}" alt="project thumbnail" />
<div class="card__body">
<h3 class="project__title">{{project.title}}</h3>
<h3 class="project__title">{{project.price}} €</h3>
</div>
</a>
</div>
</div>
{% endfor %}
I assumed that by "main-image" you mean the first image of the project.
single-project.html
<h3 class="project__title">{{project.title}}</h3>
<h3 class="project__title">{{project.price}} €</h3>
<h3 class="singleProject__subtitle">Infos zum Produkt</h3>
{{project.describtion}}
{% for projectimage in project.projectimage_set.all %}
<img src="{{projectimage.featured_images.url}}"/>
{% endfor %}
To avoid the N+1 query problem, you can also change the query in your view:
views.py
def projects(request):
projects = Project.objects.all().prefetch_related('projectimage_set')
context = {"projects":projects}
return render(request, 'projects/projects.html', context)

I want to make reply to comments feature in Django

I have a simple project and I added a comment feature there. Now I want to add comment reply feature. When I write and send the answer, it registers to sql but I cannot show it on the frontend.
models.py
class Comments(models.Model):
comment_author = models.ForeignKey(ArticleForm, on_delete=models.CASCADE, related_name='comments')
commenter_name = models.ForeignKey(User, on_delete=models.CASCADE)
comment_content = models.TextField()
commented_date = models.DateTimeField(auto_now_add=True)
def __str__(self):
return "'{}' commented by '{}'".format(self.comment_content, self.commenter_name)
class Meta:
ordering = ['-commented_date']
class ReplyComment(models.Model):
reply_comment = models.ForeignKey(Comments, on_delete=models.CASCADE, related_name='replies')
replier_name = models.ForeignKey(User, on_delete=models.CASCADE)
reply_content = models.TextField()
replied_date = models.DateTimeField(auto_now_add=True)
def __str__(self):
return "'{}' replied with '{}' to '{}'".format(self.replier_name,self.reply_content, self.reply_comment)
views.py
def detail(request,id):
article = get_object_or_404(ArticleForm,id=id)
comments = article.comments.all()
return render(request, 'detail.html', {'article': article, 'comments': comments})
def replyComment(request,id):
comments = Comments.objects.get(id=id)
if request.method == 'POST':
replier_name = request.user
reply_content = request.POST.get('reply_content')
newReply = ReplyComment(replier_name=replier_name, reply_content=reply_content)
newReply.reply_comment = comments
newReply.save()
messages.success(request, 'Comment replied!')
return redirect('index')
detail.html
<div class="container">
<a type="text" data-toggle="collapse" data-target="#reply{{comment.id}}" style="float: right;" href="">Reply</a><br>
{% if replies %}
{% for reply in replies %}
<div>
<div class="fw-bold"><small><b>Name</b></small></div>
<div style="font-size: 10px;">date</div>
<small>Reply comment</small><br>
</div>
{% endfor %}
{% endif %}
<div id="reply{{comment.id}}" class="collapse in">
<form method="post" action="/article/reply/{{comment.id}}">
{% csrf_token %}
<input name="replier_name" class="form-control form-control-sm" type="hidden">
<input name="reply_content" class="form-control form-control-lg" type="text" placeholder="Reply comment">
<button type="submit" class="btn btn-primary" style="float: right; margin-top: 5px;">Reply</button>
</form>
</div>
What I'm trying to do is pull the responses from the sql and show them below the comment
I will be glad if you can tell me a solution suitable for my codes. Thanks
Perhaps this will work:
{% for comment in comments %}
<div>{{ comment }}</div>
{% for reply in comment.replycomment_set.all %}
<div>
<div class="fw-bold"><small><b>Name {{ reply.replier_name }}</b></small></div>
<div style="font-size: 10px;">date {{ reply.replied_date }}</div>
<small>Reply comment {{ reply.content }}</small><br>
</div>
{% endfor %}
{% endfor %}

Edit item within views in Django

There is some problem, I'm trying to update the product on the client by making changes and clicking on the update button - my page is refreshing w/o updating info, so the product has the same data as before. But in the logs, the status code of the GET request is 200 and shows the updated object in the database. When I try to update through the admin Django dashboard, everything works successfully, the problem is only on the client side of the web application. What issues can there be?
Thank you in advance!
models.py
from django.db import models
from django.contrib.auth.models import User
# Create your models here.
CATEGORY = (
('Stationary', 'Stationary'),
('Electronics', 'Electronics'),
('Food', 'Food'),
)
class Product(models.Model):
name = models.CharField(max_length=100, null=True)
quantity = models.PositiveIntegerField(null=True)
category = models.CharField(max_length=50, choices=CATEGORY, null=True)
def __str__(self):
return f'{self.name}'
class Order(models.Model):
name = models.ForeignKey(Product, on_delete=models.CASCADE, null=True)
customer = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
order_quantity = models.PositiveIntegerField(null=True)
def __str__(self):
return f'{self.customer}-{self.name}'
views.py
#login_required(login_url='user-login')
#allowed_users(allowed_roles=['Admin'])
def product_edit(request, pk):
item = Product.objects.get(id=pk)
if request.method == 'POST':
form = ProductForm(request.POST, instance=item)
if form.is_valid():
form.save()
return redirect('dashboard-products')
else:
form = ProductForm(instance=item)
context = {
'form': form,
}
return render(request, 'dashboard/products_edit.html', context)
forms.py
class ProductForm(forms.ModelForm):
class Meta:
model = Product
fields = '__all__'
html template:
{% extends 'partials/base.html' %}
{% block title %}Products Edit Page{% endblock %}
{% load crispy_forms_tags %}
{% block content %}
<div class="row my-4">
<div class="col-md-6 offset-md-3 p-3 bg-white">
<h3>Edit Item</h3>
<hr>
<form>
{% csrf_token %}
{{ form|crispy }}
<input class="btn btn-info" type="submit" value="Confirm">
</form>
</div>
</div>
{% endblock %}
You have forgotten to pass POST method you are using GET.
{% extends 'partials/base.html' %}
{% block title %}Products Edit Page{% endblock %}
{% load crispy_forms_tags %}
{% block content %}
<div class="row my-4">
<div class="col-md-6 offset-md-3 p-3 bg-white">
<h3>Edit Item</h3>
<hr>
<form method="post">
{% csrf_token %}
{{ form|crispy }}
<input class="btn btn-info" type="submit" value="Confirm">
</form>
</div>
</div>
{% endblock %}

Uploading multiple images in Django with django-multiupload library

I'm trying to use the below library to implement multi upload in my Django proejct.
https://github.com/Chive/django-multiupload
boutique/models.py
class Photo(models.Model):
store = models.ForeignKey(Store)
photo = models.FileField(null=True, blank=True, upload_to='boutique/index/%Y/%m/%d')
url = models.CharField(max_length=40, null=True, blank=True, verbose_name='Image URL')
created_at = models.DateTimeField(auto_now_add=True)
def __unicode__(self):
return str(self.photo)
def get_absolute_url(self):
return reverse('cms:photo_edit', args=[self.pk])
cms/forms.py
from django import forms
from boutique.models import Photo
from multiupload.fields import MultiFileField
class PhotoCreateForm(forms.ModelForm):
class Meta:
model = Photo
fields = ['store']
attachments = MultiFileField(min_num=1, max_num=3, max_file_size=1024*1024*5)
cms/views.py
class PhotoCreateView(FormView):
model=Photo
template_name='cms/photo_new.html'
form_class = PhotoCreateForm
success_url=reverse_lazy('cms:photo')
queryset = Photo.objects.all()
def form_valid(self, form):
for each in form.cleaned_data['attachments']:
Attachment.objects.create(file=each)
return super(PhotoCreateView, self).form_valid(form)
cms/photo_new.html
{% extends 'cms/base.html' %}
{% load staticfiles %}
{% block page-header %}Add Photo{% endblock %}
{% block content %}
<form action="" method="post">
{% csrf_token %}
<table class="table table-hover store-form">
{{ form.as_table }}
</table>
<input class="btn btn-success btn-block" type="submit" name="" value="Submit">
<br>
</form>
{% endblock %}
FYI, I'm not using Django default admin, but my own customized admin, which is the app named cms. I'm also using models in the app named boutique.
When I upload photos, nothing happens and the page doesn't even move to the success url. After submitting the files, the file input field just says "Thie field is required", and I don't see any uploads on the database.
Is there something wrong on my codes?
Your Model name is Photo, then why you try to save photos at Attachment Model!
cms/views.py
class PhotoCreateView(FormView):
model=Photo
template_name='cms/photo_new.html'
form_class = PhotoCreateForm
success_url=reverse_lazy('cms:photo')
queryset = Photo.objects.all()
def form_valid(self, form):
for each in form.cleaned_data['attachments']:
Photo.objects.create(photo=each)
return super(PhotoCreateView, self).form_valid(form)
If you want to upload any file or image then you need to add enctype="multipart/form-data" to your HTML form.
cms/photo_new.html
{% extends 'cms/base.html' %}
{% load staticfiles %}
{% block page-header %}Add Photo{% endblock %}
{% block content %}
<form action="" method="post" enctype="multipart/form-data">
{% csrf_token %}
<table class="table table-hover store-form">
{{ form.as_table }}
</table>
<input class="btn btn-success btn-block" type="submit" name="" value="Submit">
<br>
</form>
{% endblock %}
Update this two file. hopefully, it'll work. If not then let me know.

How add follow button to profile in django getstream

I try to add follow button in django with Getstream.io app.
Following the getstream tutorial, django twitter, I managed to create a list of users with a functioning follow button as well as active activity feed. But when i try add follow button on user profile page, form send POST but nothing happends later.
I spend lot of time trying resolve this, but i'm still begginer in Django.
Code:
Follow model:
class Follow(models.Model):
user = models.ForeignKey('auth.User', related_name = 'follow', on_delete = models.CASCADE)
target = models.ForeignKey('auth.User', related_name ='followers', on_delete=models.CASCADE)
created_at = models.DateTimeField(auto_now_add = True)
class Meta:
unique_together = ('user', 'target')
def unfollow_feed(sender, instance, **kwargs):
feed_manager.unfollow_user(instance.user_id, instance.target_id)
def follow_feed(sender, instance, **kwargs):
feed_manager.follow_user(instance.user_id, instance.target_id)
signals.post_delete.connect(unfollow_feed, sender=Follow)
signals.post_save.connect(follow_feed, sender=Follow)
Views:
def user(request, username):
user = get_object_or_404(User, username=username)
feeds = feed_manager.get_user_feed(user.id)
activities = feeds.get()['results']
activities = enricher.enrich_activities(activities)
context = {
'user': user,
'form': FollowForm(),
'login_user': request.user,
'activities': activities,
}
return render(request, 'profile/user.html', context)
def follow(request):
form = FollowForm(request.POST)
if form.is_valid():
follow = form.instance
follow.user = request.user
follow.save()
return redirect("/timeline/")
def unfollow(request, target_id):
follow = Follow.objects.filter(user=request.user, target_id=target_id).first()
if follow is not None:
follow.delete()
return redirect("/timeline/")
Forms:
class FollowForm(ModelForm):
class Meta:
exclude = set()
model = Follow
Urls:
path('follow/', login_required(views.follow), name='follow'),
path('unfollow/<target_id>/', login_required(views.unfollow), name='unfollow'),
And user.html
<form action="{% if request.user in User.followers.all %}{% url 'unfollow' target.id %}{% else %}{% url 'follow' %}{% endif %}" method="post">
{% csrf_token %}
<input type="hidden" id="id_target" name="target" value="{{target.id}}">
<input type="hidden" id="id_user" name="user" value="{{user.id}}">
<button type="submit" class="btn btn-primary btn-sm" value="Create" />
{% if request.user in User.followers.all %}
Unfollow
{% else %}
Follow
{% endif %}
</button>
</form>
This form work in list user page:
{% for one, followed in following %}
<div class="col-md-3 col-sm-6 col-xs-12">
<div class="card">
<div class="card-body">
{% include "profile/_user.html" with user=one %}
<form action="{% if followed %}{% url 'unfollow' one.id %}{% else %}{% url 'follow' %}{% endif %}" method="post">
{% csrf_token %}
<input type="hidden" id="id_target" name="target" value="{{one.id}}">
<input type="hidden" id="id_user" name="user" value="{{user.id}}">
<button type="submit" class="btn btn-primary btn-sm" value="Create" />
{% if followed %}
Przestań obserwować
{% else %}
Obserwuj
{% endif %}
</button>
</form>
</div>
</div>
</div>
{% if forloop.counter|divisibleby:'4' %}
<div class="clearfix visible-sm-block visible-md-block visible-lg-block"></div>
{% elif forloop.counter|divisibleby:'2' %}
<div class="clearfix visible-sm-block"></div>
{% endif %}
{% endfor %}
</div>
And user list Views.py
def discover(request):
users = User.objects.order_by('date_joined')[:50]
login_user = User.objects.get(username=request.user)
following = []
for i in users:
if len(i.followers.filter(user=login_user.id)) == 0:
following.append((i, False))
else:
following.append((i, True))
login_user = User.objects.get(username=request.user)
context = {
'users': users,
'form': FollowForm(),
'login_user': request.user,
'following': following
}
return render(request, 'uzytkownicy.html', context)