Restricting upload until the admin approved the uploaded file in Django - python

i am new in django.I am doing a project where user can upload image.But i want to make sure that the user can not upload image or file until the admin approved it.now how can i do this,have prepared models for this,but for inexperience in django i can not complete it or you can say i have no clue,now help me if you can, i am giving a very simple code here.
This is my forms.py for the upload image...
from django import forms
class DocumentForm(forms.Form):
photo = forms.ImageField(
label='Select a file'
)
and this is my models.py...
from django.db import models
from django.contrib.auth.models import User
class Photo(models.Model):
name = models.CharField(max_length = 100)
photo = models.ImageField(upload_to = 'photos', blank=False,null=True)
approved = models.nullBooleanField()
uploaded_time = models.DateTimeField(auto_now_add = True,auto_now = False)
description = models.CharField(max_length = 80 , blank = False , null = True)
approved_by = models.CharField(max_length = 100)
user = models.ForeignKey(User)
here i make a field for approved as a Boolean field.
and this is view for file/image upload...
def UserImageUpload(request):
if request.method == 'POST':
form = DocumentForm(request.POST,request.FILES)
if form.is_valid():
if approved:
newdoc = Photo(photo = request.FILES['photo'],user = request.user)
newdoc.save()
else:
else:
form = DocumentForm()
uploaded_image = Photo.objects.all()
return render_to_response('myprofile/user_image_upload.html',{'uploaded_image':uploaded_image,'form':form},context_instance = RequestContext(request))
and this is the template for file or image upload...
{% extends 'base.html'%}
{% block title%}User Image Upload {% endblock %}
{%block content%}
<form action="" method="post" enctype="multipart/form-data">
{% csrf_token %}
<p>{{ form.non_field_errors }}</p>
<p>{{ form.photo.label_tag }} {{ form.photo.help_text }}</p>
<p>
{{ form.photo.errors }}
{{ form.photo }}
</p>
<p><input type="submit" value="Upload" /></p>
</form>
{%endblock%}

I think it should be like this:
1.User upload image and you set approved to false.
2.On admin page you can change approved to true.
3.Before you display image on site you check if it is approved.

Related

Image from an ImageField ModelForm not uploading into the server

Hi so I am new to Django and one of the things I'm trying to do is make a simple gallery application. Somehow I can't add images through the server via the forms if I use a Model Form although I can do it using a plain form. I've tried a lot of the stuff in here and also tried some Youtube stuff but it didn't still work.
Here is my models.py
from django.db import models
from django.urls import reverse
from django.core.validators import validate_image_file_extension
from django.core.files.storage import FileSystemStorage
fs = FileSystemStorage(location='/media')
class FavoriteImages(models.Manager):
def get_queryset(self):
return super().get_queryset().filter(favorite=True)
# Create your models here.
class Photo(models.Model):
name = models.CharField(max_length=120, null=True)
photo = models.ImageField(storage=fs, upload_to='media/', validators=[validate_image_file_extension])
date_uploaded = models.DateTimeField(auto_now=True)
favorite = models.BooleanField(default=False, blank=False)
slug = models.SlugField(null=True, blank=True)
gallery = models.Manager()
gallery_favorites = FavoriteImages()
class Meta:
ordering = ['-date_uploaded']
My Views.py
from PIL import Image
def image_new(request, *args, **kwargs):
Image.init()
form = PhotoForm(data=request.POST, files=request.FILES)
if request.method == 'POST':
form = PhotoForm(request.POST, request.FILES)
if form.is_valid():
form.save()
redirect('../all')
context = {
'form': form
}
return render(request, "form.html", context)
My forms.py
class PhotoForm(forms.ModelForm):
name = forms.CharField(label='',widget=forms.TextInput(attrs={'class':'form-control', 'placeholder':'Title'}))
photo = forms.ImageField(widget=forms.FileInput(attrs={'class':'form-control'}))
favorite = forms.BooleanField(label='Mark as Favorite',widget=forms.CheckboxInput(attrs={'class':'form-check-input'}))
class Meta:
model = Photo
fields = ['name',
'photo',
'favorite']
my .html
{% extends "base.html" %}
{% block content %}
{% if form.is_multipart %}
<form enctype="multipart/form-data" method="post">
This form is a multipart.
{% else %}
<form method="post">
{% endif %}
{% csrf_token %}
{% if form.media %}
{{ form.media }}
{% endif %}
{{ form.as_p }}
<input type="submit" class="btn btn-primary" value="Save"/>
</form>
{% endblock %}
I've placed this in the settings:
MEDIA_URL = 'media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
Something I noticed:
The media folder (root) remains empty, but Model.photo has an url. (not null)
How do I modify my form so that the image gets posted?
EDIT: I fixed it by changing the widget of the ImageField. I don't know why it works now, but it does. Thanks for all the help
Why all those {% if %} in the template? I think it's unecessary. I would write it as follows,
{% extends "base.html" %}
{% block content %}
<form enctype="multipart/form-data" method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit" class="btn btn-primary" value="Save"></button>
</form>
{% endblock %}
Your form can also be simplified as such,
class PhotoForm(forms.ModelForm):
name = forms.CharField(label='',widget=forms.TextInput(attrs={'class':'form-control', 'placeholder':'Title'}))
photo = forms.ImageField()
favorite = forms.BooleanField(label='Mark as Favorite',widget=forms.CheckboxInput(attrs={'class':'form-check-input'}))
'''
You don't need the Meta class when inheriting from forms.ModelForm. I think the widgets aren't necessary, unless you need to style with CSS specifics.
Your view can also be simplified quite a bit. You don't need PIL Image unless you are modifying your image.
I would write like this,
def image_new(request, *args, **kwargs):
form = PhotoForm()
if request.method == 'POST':
form = PhotoForm(request.POST, request.FILES)
if form.is_valid():
form.save()
redirect('../all')
context = {
'form': form
}
return render(request, "form.html", context)
Django will take care of saving the image to your media folder and assigning it to the ImageField in the model.

How to auto-fill fields while updating django forms?

I am creating a to-do app in django and while updating a task, i want to auto-fill the fields with previous data. Where am i messing up?
This is my views.py for the same:-
task = get_object_or_404(ToDoList, id=id)
if request.method == "POST":
form = UpdateTaskForm(request.POST)
if form.is_valid():
task.description = form.cleaned_data['description']
task.save()
form.save()
return redirect(reverse('list'))
else:
form = UpdateTaskForm(instance=task)
context = {
'form':form,
'task':task,
}
return render(request, 'TaskList/update.html', context)
and this is my forms.py:-
class Meta:
model = ToDoList
fields = ['title', 'description', 'due_date', 'completed']
here is my template file:-
{% load crispy_forms_tags %}
{% block title %} Updating task {% endblock %}
{% block content %}
<form method="post">
{% csrf_token %}
{{ form|crispy }}
<button type="submit" class="btn btn-success" value="Submit"> Save </button>
</form>
{% endblock %}
and here is my models.py:-
from django.utils import timezone
# Create your models here.
class ToDoList(models.Model):
title = models.CharField(max_length=120)
description = models.TextField(help_text='Explain your task!', blank=True)
created_date = models.DateTimeField(default=timezone.now())
due_date = models.DateTimeField(default=timezone.now())
completed = models.BooleanField(default=False)
#Author foreign key
def __str__(self):
return self.title
If you are updating an instance you must also pass the same instance in the POST method also, so after
if request.method == "POST": add form = UpdateTaskForm(request.POST,instance=task)
I guess you are using crispy forms, so according to this question here They are rendering the forms using {% crispy form %} instead of the way you have done as {{ form|crispy }} maybe that is the issue.

How correctly save multiple files in django?

I need form where user can create article with several images. I use django-multiupload app for image field. I can select several images but when I try to submit the form I have message under the image field: "Field is empty and field is required". Where is my mistake? Why I have such message when image field is not empty?
Also maybe someone can advice good examples or apps to save several images. I would be very grateful for any help.
models.py:
class Article(models.Model):
description = models.TextField(_('Description'))
class Image(models.Model):
article= models.ForeignKey(Article, on_delete=models.CASCADE)
image = models.FileField(_('Image'), upload_to='images/%Y/%m/%d/')
forms.py:
class ArticleForm(forms.ModelForm):
class Meta:
model = Article
fields = ('description', )
image = MultiFileField()
def save(self, commit=True):
instance = super(ArticleForm, self).save(commit)
for each in self.cleaned_data['image']:
Image.objects.create(image=each, article=instance)
return instance
views.py:
def article_add(request):
data = dict()
if request.method == 'POST':
article_form = ArticleForm(request.POST, request.FILES)
if article_form.is_valid():
article = article_form.save(commit=False)
******
article.save()
data['form_is_valid'] = True
articles = Article.objects.all
context = {'articles': articles}
context.update(csrf(request))
data['html_article'] = render_to_string('project/article_list.html', context)
else:
data['form_is_valid'] = False
else:
article_form = ArticleForm()
context = {'article_form': article_form}
data['html_article_form'] = render_to_string('project/article_add.html', context, request=request)
return JsonResponse(data)
article_add.html:
{% load widget_tweaks %}
<form method="post" action="{% url 'article_add' %}" class="article-add-form">
{% csrf_token %}
{% for field in article_form %}
<div class="form-group{% if field.errors %} has-danger{% endif %}">
<label class="form-control-label" for="{{ field.id_for_label }}">{{ field.label }}</label>
{% render_field field class="form-control" %}
{% for error in field.errors %}
<div class="form-control-feedback">{{ error }}</div>
{% endfor %}
</div>
{% endfor %}
<button type="submit">Submit</button>
</form>
Try adding "min_num" constraint on the image field,
image = MultiMediaField(min_num=1, media_type='image')
EDIT
def article_add(request):
if request.method == 'POST':
article_form = ArticleForm(request.POST, request.FILES)
if article_form.is_valid():
article = article_form.save(commit=False)
******
article.save()
#assume you have already a view in the name 'article_list'.
return redirect('article_list')
else:
article_form = ArticleForm()
context = dict(article_form=article_form)
return render(request, 'project/article_add.html', context)
The problem maybe because you were trying to render two templates in a single view, also when using django template rendering render is a shortcut function, which is mostly preferred to use, rather than string converting and parsing into json.
Also, 'article_list' must be another view, which shows the list of all the articles, after adding a new article, you should consider redirecting to the list view. Here you were trying to render multiple templates, in a single view. You could make of something like this in your list view,
def article_list(request):
articles = Article.objects.all()
context = dict(articles=articles)
return render(request, 'project/article_list.html', context)
Although, these are my personal opinion regarding the code you just shared. Try this approach...

data is not inserting in database when I click submit button

I have created my first app in Django (1.10.5) / Python 3.4. I have a login page and a register page. Which is working fine.
I can create new user and login with that id. Now after the login I want user to fill a form with some information and click on submit. And the information should get stored in the database.
So I created a model first : Model.py
class UserInformation(models.Model):
firstName = models.CharField(max_length=128)
lastName = models.CharField(max_length=128)
institution = models.CharField(max_length=128)
institutionNumber = models.CharField(max_length=128)
cstaPI = models.CharField(max_length=128)
orchidNumber = models.CharField(max_length=128)
This has created a table in the DB.
forms.py
class UserInformationForm(ModelForm):
class Meta:
model = UserInformation
fields = '__all__'
views.py
def home(request):
form = UserInformationForm()
variables = { 'form': form, 'user': request.user }
return render(request,'home.html',variables)
home.html
{% extends "base.html" %}
{% block title %}Welcome to Django{% endblock %}
{% block head %}Welcome to Django{% endblock %}
{% block content %}
<p> Welcome {{ user.username }} !!! Logout<br /><br /> </p>
<form method="post" action=".">{% csrf_token %}
<table border="0">
{{ form.as_table }}
</table>
<input type="submit" value="Submit" style="position:absolute"/>
</form>
{% endblock %}
But when I click on submit button, It does not insert data into my table.
here is the answer, we need to use the request.POST
def home(request):
if request.method == 'POST':
form = UserInformationForm(request.POST)
form.save()
return HttpResponseRedirect('/home/')
else:
form = UserInformationForm()
variables = { 'form': form, 'user': request.user }
return render(request,'home.html',variables)
the first: you need add urls.py to you app
the second: you need to change your views.py to lool like this
`
info = UserInformation()
lastName = request.POST.get('lastName')
...
info.save()
`

Django Image Field not Updating on the Front

I am trying to get my app to validate the image upload field in my app's template and save any new image that is uploaded. Everything works fine on the admin side of things but when I make an image change on the front, it doesn't get saved.
Here is my model
def imageupload(instance, filename):
return os.path.join('static/petition-photos/', filename)
# Create your models here.
class Petition(models.Model):
title = models.CharField(max_length= 90, default="Enter petition title here")
created_on = models.DateTimeField(auto_now_add=True)
image = models.ImageField(null=False, upload_to=imageupload)
video = models.CharField(max_length=600, default="Enter an external video link")
petition = models.TextField(null=False, default="Type your petition here")
created_by = models.ForeignKey(User)
Here is my view class:
class NewPetitionView(generic.edit.CreateView):
model = Petition
template_name = 'petition/petition_form.html'
fields= ['title','petition', 'image', 'video']
success_url = '/dashboard/'
def form_valid(self, form):
form.instance.created_by = self.request.user
return super(NewPetitionView, self).form_valid(form)
And this is my form template:
{% include 'layout/header.html' %}
{% block content %}
<form action="" method="post">
{{form.as_p}}
<button type="submit">Submit</button>
{% csrf_token %}
</form>
{% endblock %}
When I upload an image to a new post or try to edit the image field of one of the posted items, I get a "This field is required" notification.
What am I doing wrong?
You need in your <form> add enctype="multipart/form-data" in order to let file upload work.
<form action="" method="post" enctype="multipart/form-data">
django doc.

Categories

Resources