Django: How can I changes values via views.py - django

I am trying to make a "upload" page so that I can upload a file and process to postgres DB using pd.to_sql(). All the data has been succefuly recorded into DB, but cannot change the values of "is_recorded" and "has_issue". Here is the files I am working on so far.
In upload/models.py
from django.db import models
class Upload(models.Model):
file_name = models.FileField(upload_to='uploads', max_length=255)
uploaded = models.DateTimeField(auto_now_add=True)
# When uploaded successfully
is_recorded = models.BooleanField(default=False)
# When it has a problem to fix
has_issue = models.BooleanField(default=False)
def __str__(self):
return f'{self.file_name}: {self.id}'
In views.py
import os
from django.shortcuts import render
from core.db_implements import upload_csv_to_DB
from upload.forms import UploadForm
from upload.models import Upload
def upload_view(request):
error_message = None
success_message = None
form = UploadForm(request.POST or None, request.FILES or None)
if form.is_valid():
form.save()
form = UploadForm()
try:
obj = Upload.objects.get(is_recorded=False)
recorded, issue, success_message, error_message = ***upload_csv_to_DB***(obj)
obj.is_recorded = recorded
obj.has_issue = issue
obj.save()
success_message = success_message
error_message = error_message
except:
error_message = 'Something went wrong.'
context={
'form': form,
'success_message': success_message,
'error_message': error_message,
}
return render(request, 'upload/upload.html', context)
In forms.py
from django import forms
from django.db.models import fields
from django.forms.fields import FileField
from django.forms.models import ModelFormMetaclass
from .models import Upload
class UploadForm(forms.ModelForm):
# file_name = forms.FileField(max_length=255, label=False)
class Meta:
model=Upload
fields = ('file_name',)
widgets = {
'file_name': forms.FileInput(
attrs={
'class': 'form-control',
}
)
}
I am outsource the function (upload_csv_to_DB) which takes file object and convert to dataframe and record into DB. If its success, recorded=True with sucess_message supposed to be returned, however, if somethings wrong, issue=True with error_message supposed to be returned. Anyways recorded and issue are always False, and having error_message from except clause 'Something went wrong.'. Please advise me...

I figured out the reason. I did not initialize the return value of outsourced function, upload_csv_to_DB. After initialize the returned values to be, everything works as intended. Here is the code which solves the problem.
In upload_csv_to_DB.py:
def upload_csv_to_DB(csv_obj):
recorded = False
issue = False
success_message = None
error_message = None
upload_file = csv_obj.file_name.path
...
return (recorded, issue, success_message, error_message)
In views.py:
def upload_view(request):
error_message = None
success_message = None
recorded =False
issue = False
if request.method == 'POST':
form = UploadForm(request.POST, request.FILES)
if form.is_valid():
form.save()
try:
obj = Upload.objects.get(is_recorded=False)
recorded, issue, success_message, error_message = upload_csv_to_DB(obj)
obj.is_recorded = recorded
obj.has_issue = issue
obj.save()
success_message = success_message
error_message = error_message
except:
error_message = 'Something went wrong.'
else:
form = UploadForm()
context={
'form': form,
'success_message': success_message,
'error_message': error_message,
}
return render(request, 'upload/upload.html', context)

Related

Django Multiple Image Upload Using form

This can upload single image. But i want to upload multiple image like insta do. In instagram multiple images are stored in a slider. I don't understand files = request.FILES.getlist('image') how can i iterate this this list
Views.py file
#login_required
def index(request):
images = Image.objects.all()
users = User.objects.filter(is_superuser=False)
prof = Profile.objects.get(user=request.user)
actions = Action.objects.exclude(user=request.user)
following_ids = request.user.following.values_list('id', flat=True)
if request.method == "POST":
form = ImageCreateForm(request.POST, request.FILES)
files = request.FILES.getlist('image')
if form.is_valid():
description = form.cleaned_data["description"]
image = form.cleaned_data["image"]
new_item = form.save(commit=False)
new_item.user = request.user
new_item.save()
create_action(request.user, 'Uploaded Image', new_item)
messages.success(request, "Image Added Successfully")
return redirect(new_item.get_absolute_url())
else:
form = ImageCreateForm(data=request.GET)
if following_ids:
# If user is following others, retrieve only their actions
actions = actions.filter(user_id__in=following_ids)
actions = actions.select_related('user', 'user__profile').prefetch_related('target')[:10]
return render(request, "account/index.html", {
'section': 'index',
'images': images,
'prof': prof,
'actions': actions,
'users': users,
'form': form,
})
forms.py file
from django import forms
from urllib import request
from django.core.files.base import ContentFile
from django.utils.text import slugify
from .models import Image
class ImageCreateForm(forms.ModelForm):
image = forms.ImageField(widget=forms.ClearableFileInput(attrs={'multiple': True}))
class Meta:
model = Image
fields = ('description',)
def clean_url(self):
image = self.cleaned_data['image']
valid_extensions = ['jpg', 'jpeg']
extension = image.rsplit('.', 1)[1].lower()
if extension not in valid_extensions:
raise forms.ValidationError('The Given URL does not match valid image extensions.')
return image
def save(self, force_insert=False, force_update=False, commit=True):
image = super().save(commit=False)
url = self.cleaned_data['image']
name = slugify(image.description)
image_name = f'{name}'
image.image.save(image_name, ContentFile(url.read()), save=False)
if commit:
image.save()
return image
admin.py file
#admin.register(Image)
class ImageAdmin(admin.ModelAdmin):
list_display = ['slug', 'image', 'description', 'created']
list_filter = ['created']
You can just loop throught it:
for afile in request.FILES.getlist('image'):
mymodel = MyModel()
mymodel .pic = afile
mymodel .save()
Of course you need to make sure you can save the images in your model.

How to check if `MultiSelectField` is empty or not in Django?

In my model I have a field department which is a MultiSelectField and I give the blank=True to that field for some reasons. Now I want to check if user fills the field or not. I have tried to get data from request.POST and gave it a condition using len() function like this if len(field) == 0: but I got an error. Everything works just fine until I added teacher_year = request.POST['teacher_year']
models.py
class CustomUser(AbstractUser):
teacher_department = MultiSelectField(choices=department_choice, blank=True)
forms.py
class TeacherRegisterForm(UserCreationForm):
class Meta(UserCreationForm):
model = CustomUser
fields = ['teacher_year', ...]
views.py
def teacherRegisterView(request):
form = TeacherRegisterForm()
template_name = "attendance/login-register/teacher_register.html"
if request.method == "POST":
form = TeacherRegisterForm(request.POST)
teacher_year = request.POST['teacher_year']
if len(teacher_year) == 0:
messages.warning(request, "Just a remind! You didn't select deparment!")
return redirect('teacher_register')
elif form.is_valid():
form.save()
messages.success(request, "Your account was created! You can log in now.")
return redirect('/')
return render(request, template_name, {'form': form})
the error I got
django.utils.datastructures.MultiValueDictKeyError: 'teacher_year'
MultiValueDict is inherited from normal dict. So you can use get() method with it:
teacher_year = request.POST.get('teacher_year') # if request.POST doesn't contain teacher_year it returns None
if teacher_year:
...

Can't work modal form with method POST in Django

Thats my first project in Django. I want to make table and add items with modal form. I use Mysql database. items which addes manually from phpmyadmin already exist on table but when i try add from modal form it cant added.
views.py
from django.shortcuts import render
from django.http import HttpResponse
from .models import Client
def viewpost(request):
post_list = Client.objects.all()
context = {
'posts': post_list
}
return render(request, 'mysite/viewtable.html', context)
def add_client(request):
if request.method == 'POST':
post = Client()
post.name = request.POST.get('name')
post.surname = request.POST.get('surname')
post.address = request.POST.get('address')
post.gender = request.POST.get('gender')
post.age = request.POST.get('age')
post.save()
return render(request, 'mysite/viewtable.html')
else:
return render(request, 'mysite/viewtable.html')
url.py:
from django.urls import path
from . import views
urlpatterns = {
path('viewtable/', views.viewpost, name='viewpost'),
path('viewtable/#add_data_Modal', views.add_client, name='add_client'),
}
Before the table and modal form didnt work together. If table worked then modal form didnt add to database or conversely. Now the're work together: Modal form add to database then table show data on page. But when i refresh page data add to databse twice.
views.py:
def viewpost(request):
post_list = Persona.objects.all()
context = {
'posts': post_list
}
if request.method == 'POST':
if request.POST.get('name') and request.POST.get('surname') and request.POST.get('address'):
post = Client()
post.name = request.POST.get('name')
post.surname = request.POST.get('surname')
post.address = request.POST.get('address')
post.age = request.POST.get('age')
post.save()
return render(request, 'mysite/viewtable.html', context)
else:
return render(request, 'mysite/viewtable.html')
Thats SOLVED. Here's view
def viewpost(request):
post_list = Persona.objects.all()
if request.method == 'POST':
if request.POST.get('name') and request.POST.get('surname') and
request.POST.get('address'):
post = Persona()
post.name = request.POST.get('name')
post.surname = request.POST.get('surname')
post.address = request.POST.get('address')
post.age = request.POST.get('age')
post.save()
return HttpResponseRedirect('/viewtable')
else:
return render(request, 'mysite/viewtabel.html', {'posts': post_list}

Django IntegrityError; NOT NULL constraint failed

I am trying to save an instance of a model but to no avail.
Below is my model;
class AudioFile(models.Model):
name = models.CharField(max_length=100,default='')
audio_file = models.FileField()
uploader = models.ForeignKey(User,default='')
def __unicode__(self):
return self.name
I have the below form;
class AudioFileForm(forms.ModelForm):
class Meta:
model = AudioFile
fields = ['name', 'audio_file']
def clean_audio_file(self):
audio = self.cleaned_data['audio_file']
if audio:
if audio._size > 5*1024*1024:
raise ValidationError("File too large ( > 5mb )")
if os.path.splitext(audio.name)[1] != ".mp3":
raise ValidationError("We only support mp3!")
return audio
else:
raise validationError("Couldn't read uploaded file")
And I have the below view to handle the submitted form;
form = AudioFileForm(request.POST, request.FILES)
if form.is_valid():
form.cleaned_data['uploader'] = request.user //view requires login
form.save()
return HttpResponseRedirect(
reverse('home_audio',kwargs={'pk':audio_file.pk})
)
else:
return HttpResponse(form.errors)
But on submission I get the error; IntegrityError at /uploadaudio
NOT NULL constraint failed: stationrunner_audiofile.uploader_id /uploadaudio is the URL correspoding to the view and stationrunner is my app's name.
Someone please help out.
Try changing the view:
form = AudioFileForm(request.POST, request.FILES)
if form.is_valid():
audio_file = form.save(commit=False) // This will not hit the database, and no IntegrityError will be raised
audio_file.uploader = request.user // Tack on the user,
audio_file.save()
return HttpResponseRedirect(
reverse_lazy('home_audio',kwargs={'pk':audio_file.pk}) // Use reverse lazy to prevent circular import issues.
)
else:
return HttpResponse(form.errors)
Also you could fix some issues with the model:
from django.conf import settings
from django.db import models
class AudioFile(models.Model):
name = models.CharField(max_length=100) // If the field is not allowed to be blank, the default blank does not make sense.
audio_file = models.FileField(upload_to="audio_files") // Without this parameter file field does not work.
uploader = models.ForeignKey(settings.AUTH_USER_MODEL) // This should reference the user model declared in your settings file.
def __unicode__(self):
return self.name

Django model doesn't relate itself to User through ForeignKey

my question is about modelforms, models and instances. After doing some troubleshooting I think my problem is that either the user field from UserFile doesn't associate itself to the auth.User or that the modelform doesn't pass the instance of auth.User. The error is at the dynamic pathing - file_destination - when I try self.user it can't find the user :/
# Model
class UserFile(models.Model):
user = models.ForeignKey('auth.User', related_name='user_file', primary_key=True, unique=True)
user_file = models.FileField(upload_to=file_destination, null=True)
def __unicode__(self):
return self.user_file.name
# View
def login_index(request):
template = 'loginIndex.html'
context = Context()
if request.user.is_authenticated():
if request.method == 'POST':
form = UserUpload(request.POST, request.FILES, instance=request.user)
context.update({'form': form})
if form.is_valid() and form.is_multipart():
instance = UserFile(user_file=request.FILES.get('user_file'))
instance.save()
else:
form = UserUpload()
context.update({'form': form})
return render(request, template, context)
else:
return render(request, template, context)
# Form
class UserUpload(ModelForm):
user_file = forms.FileField(required=False, widget=forms.ClearableFileInput, label='Upload')
class Meta:
model = UserFile
fields = ['user_file']
def clean_user_file(self):
check_user_file = self.cleaned_data.get('user_file')
if check_user_file:
if check_user_file.size > 5120000:
raise ValueError('File is too big for upload')
return check_user_file
# The problem arises when I submit the instance, which saves the file from the form to upload_to=file_destination
# In file_destination I get an error on self.user.username saying || DoesNotExist at "" UserFile has no user.
# My self.user is an None object.
def file_destination(self, filename):
filename = name_generator()
url = "%s/%s/%s" % (self.user.username, 'uploads' ,filename)
return url
You need to manually set the user field on your UserFile instance:
if form.is_valid():
instance = form.save(commit=False)
instance.user = request.user
instanve.save()
form.save_m2m() # add this if you add m2m relationships to `UserFile`
Also, it is a good idea to redirect after the form handling succeeds:
from django.shortcuts import redirect
# ...
return redirect("view-name")