How to get Filename in DjangoWebApp based on a Model containing FileField? - python

I making a email delivery WebApp, I have an Email Class with uploadcsvfile to upload the .csv contact file from the user's computer to server at location CONTACT_DIR, what I'm unable to figure out is how to get the saved contacts_some_char.csv name in my views.py, the purpouse of getting it's name is so that I can parse the email list and send email to them.
I have my model.py as follows :
class Email(models.Model):
fromemail = models.EmailField(blank = False, max_length = 254)
uploadcsvfile = models.FileField(upload_to = 'Contacts', blank = False)
subject = models.CharField(blank=False,max_length = 254)
bodyHeading = models.CharField(blank = False,max_length = 254)
bodytext = models.TextField(blank = False)
name = models.CharField(blank = False,max_length = 254)
Here is my views.py :
def index(request):
if request.method == 'POST':
email_form = EmailForm(request.POST, request.FILES)
if email_form.is_valid():
email_form.save(commit = True)
print(Email.uploadcsvfile)
contacts = Contacts()
#path = settings.CONTACT_DIR
f = open(settings.CONTACT_DIR+"/"+str(uploaded_file_name))
csv_f = csv.reader(f)
Emails = []
Names= []
L_Names = []
for x in csv_f:
Emails.append(x[0])
Names.append(x[1])
L_Names.append(x[2])
f.close()
contacts.ListOfEmails = json.dumps(Emails)
contacts.ListOfFirstNames = json.dumps(Names)
contacts.ListOfLastNames = json.dumps(L_Names)
contacts.save()
Here is forms.py for the same :
from django import forms
from dcsvreader.models import Email
class EmailForm(forms.ModelForm):
class Meta():
model = Email
fields = "__all__"
A.K.A How do i get uploaded_file_name in views.py, I'm reading in various QnA at S.O that this is related to FileDescriptor but can't find how exactly also, print(Email.uploadcsvfile) gives <django.db.models.fields.files.FileDescriptor object at 0x03F7DF90> as output.

request.FILES is a dictionary-like object containing all uploaded files and the uploadcsvfile is the key in which you are making a POST request. Hence, request.FILES['uploadcsvfile'] will hold the particular file as InMemoryUploadedFile and it has a variable .name which holds the filename
Try this,
file_name = request.FILES['uploadcsvfile'].name
Reference
uploadfile.name
request.FILES

I'm pretty new to django myself but it looks like here:
print(Email.uploadcsvfile)
You're trying to print a class attribute rather than an attribute of an instance.
Have you tried the following?
print(email_form.uploadcsvfile.name)

Related

How to filter exported data by a value on database using django export import

I want to export a student data from my database and filter it by roles column.
Views.py
def export_siswa(request):
user = userResource()
dataset = user.export()
response = HttpResponse(dataset.xls, content_type='application/vnd.ms-excel')
response['Content-Disposition'] = 'attachment; filename=Data_Siswa.xls'
return response
resource.py
class userResource(resources.ModelResource):
username = Field(attribute='username', column_name='Username')
namadepan = Field(attribute='namadepan', column_name='Nama depan')
namabelakang = Field(attribute='namabelakang',column_name='Nama belakang')
email = Field(attribute='email',column_name='Email')
jeniskelamin = Field(attribute='jeniskelamin',column_name='Jenis kelamin')
tanggallahir = Field(attribute='tanggallahir',column_name='Tanggal lahir')
agama = Field(attribute='agama',column_name='Agama')
alamat = Field(attribute='alamat',column_name='Alamat')
telepon = Field(attribute='telepon',column_name='Telepon')
class Meta:
model = modelUser
fields = ['username','namadepan','namabelakang','email','jeniskelamin','tanggallahir','agama','alamat','telepon','role']
export_order = ['username','namadepan','namabelakang','email','jeniskelamin','tanggallahir','agama','alamat','telepon','role']
That is my code for the views and resource.py .. but they show all of the data .. i want the exported data is a student with "student" roles

django download a file filtered from a list of files

I'm working on a website where I have multiple excel files uploaded by users and stored in the DB, then a user chooses a file's name and date from a dropdown list and this specific file should be downloaded to him. right now I can get the File object that he requested but can't download it correctly.
This is my Models.py
class File(models.Model):
file_name = models.TextField(max_length=1000, default='myFile')
created_at = models.DateTimeField(
default=datetime.datetime.now().replace(microsecond=0))
file = models.FileField()
file_class = models.CharField(
max_length=20, default='')
def __str__(self):
return self.file_name
This is the part where I store the file in Views.py:
modelFile = File()
now = datetime.datetime.now().replace(microsecond=0)
file_class = request.POST['select_course']
Fname = request.POST['file_name']
myFile = convertToBinaryData(uploaded_fileName)
xlfile = ContentFile(myFile)
modelFile.file.save(Fname, xlfile)
modelFile.file_class = file_class
modelFile.created_at = now
modelFile.file_name = Fname
modelFile.save()
And here is where I retrieve and download the file in Views.py :
def viewTrial(request):
if request.method == "POST":
chosen_filename = request.POST['select_trial']
chosen_date = request.POST['select_trial2']
date = pd.to_datetime(
chosen_date, infer_datetime_format=True).strftime('%Y-%m-%d %H:%M')
FileToView = File.objects.filter(created_at__contains=date).filter(
file_name__contains=chosen_filename)
response = HttpResponse(content_type='application/ms-excel')
response['Content-Disposition'] = 'attachment; filename=%s' % chosen_filename+".xls"
return response
else:
return render(request, "model/trials.html", {})
this code downloads an excel file with only the file name written in it, I've seen multiple questions here regarding this issue and the downloading, and none worked out for me.
if I changed the FileToView to be like this:
FileToView = File.objects.filter(created_at__contains=date).filter(
file_name__contains=chosen_filename).values('file')
then the excel file has a Queryset written in it like this:
{'file': 'myTest'}
where 'myTest' is the file name.
the different thing that I have is that I need to download the file that I've filtered from a list of files, I've been trying for a week now since I'm new to django, and I'll be thrilled to find a solution!
any help is appreciated!

Django REST Framework received JPEG file as a String to ImageField

I have a model in Django like:
from django.db import models
from django.contrib.auth.models import User
from datetime import datetime
# Create your models here.
class UserDetails(models.Model):
def getFileName(self, filename):
return 'profile_pics/'+str(self.user.id)+'/'+filename
user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
profile_picture = models.ImageField(upload_to=getFileName, blank = True)
country = models.CharField(max_length = 50, default='UK')
gender = models.CharField(max_length=10, default='NA')
birthday = models.DateField(default=datetime.now())
phone = models.CharField(max_length=15)
verified = models.BooleanField(default=False)
def __str__(self):
try:
return self.user.username
except:
return 'Deleted User - '+str(self.phone)
Then, I created a REST API that accepts Multipart requests to create a new user as well as save the user_details for the user. I am making the multipart POST request from my app in Flutter with the Image for the profile picture. The image is coming in the body of the request as a String instead of coming in as a file, where I could have read it with request.FILES['profile_picture']. The body of the request that I am getting by doing a print(request.data) is as follows:
Data: <QueryDict: {
'username': ['jonsnow'],
'first_name': ['Jon'],
'last_name': ['Snow'],
'email': ['jonsnow#got.com'],
'password': ['jonsnow'],
'country': ['UK'],
'gender': ['Male'],
'birthday': ['2020-4-28'],
'phone': ['5198189849'],
'profile_picture': ['����\x00\x10JFIF\x00\x01\x01\x00\x00\x01\x00\x01\x00\x00��\x00�\x00\t\x06\x07\x08\x07\x06\t\x08\x07\x08\n\n\t\x0b\r\x16\x0f\r\x0c\x0c\r\x1b\x14\x15\x10\x16 \x1d"" \x1d\x1f\x1f$(4,$&1\'\x1f\x1f-=-157:::#+?D?8C49:7\x01\n\n\n\r\x0c\r\x1a\x0f\x0f\x1a7%\x1f%77777777777777777777777777777777777777777777777777��\x00\x11\x08\x019\x01�\x03\x01"\x00\x02\x11\x01\x03\x11\x01��\x00\x1c\x00\x00\x02\x03\x01\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x04\x02\x05\x06\x01\x07\x00\x08��\x00Q\x10\x00\x02\x01\x03\x02\x03\x05\x04\x06\x06\x07\x07\x03\x03\x01\t\x01\x02\x03\x00\x04\x11\x12!\x051A\x06\x13"Qa2q��\x14B����\x07#3Rr�\x154Sbs��\x16$C����5��%c�DtEFd����\x17��\x00\x1a\x01\x01\x01\x01\x01\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02\x03\x04\x05\x06��\x00(\x11\x01\x01\x00\x02\x01\x04\x02\x02\x02\x02\x03\x01\x00\x00\x00\x00\x00\x01\x02\x11\x03\x12!1A\x04\x13\x14Q\x05"aqBR�\x15��\x00\x0c\x03\x01\x00\x02\x11\x03\x11\x00?\x00�Cl�0ɵX��¸�iB�k; ...\uebe8?��']
}>
And print(request.FILES) is coming as: Files: <MultiValueDict: {}>
So, I made the Multipart REST API to handle this request like:
class SignUp(APIView):
parser_classes = [MultiPartParser,]
authentication_classes = [CsrfExemptSessionAuthentication]
permission_classes = [AllowAny]
def post(self, request, format=None):
data = request.data
print('\n\nFiles: '+str(request.FILES)+'\n\n');
print('\n\nData: '+str(data)+'\n\n');
print('\n\nData: '+str(request.META)+'\n\n');
## Creating a basic user
user = User.objects.create_user(username=data['username'], first_name = data['first_name'], last_name = data['last_name'], email = data['email'], password = data['password'])
user.save()
user_details = UserDetails()
user_details.user = user
rec_img_str = data['profile_picture']
rec_img_bytes = rec_img_str.encode('utf-8')
rec_img_writer = BytesIO(rec_img_bytes)
uploaded_img = InMemoryUploadedFile(rec_img_writer, None, 'sample.jpg', 'image/jpeg', None, 'utf-8')
user_details.profile_picture = uploaded_img
user_details.country = data['country']
user_details.gender = data['gender']
user_details.birthday = datetime.strptime(data['birthday'], '%Y-%m-%d').date()
user_details.phone = data['phone']
user_details.verified = False
user_details.save()
return Response({'Message': 'Profile Created Successfully'})
Here, I read the JPG image that comes as a string in the field profile_picture, converted it to Byte form, put it into BytesIO(), and then stored it in user_details.profile_picture as an InMemoryUploadedFile. It saves as sample.jpg in my MEDIA directory, but when I try to open it, it comes as a blank image.
So, how do I save the JPEG image that is coming in as a string to a ImageField in Django?
Here's my Flutter code, if it is needed for reference:
void submit() async {
MultipartRequest request = MultipartRequest("POST",
Uri.parse("http://10.0.2.2:8000/services/authentication/signup/"));
request.fields['username'] = this.username.text;
request.fields['first_name'] = this.first_name.text;
request.fields['last_name'] = this.last_name.text;
request.fields['email'] = this.email.text;
request.fields['password'] = this.password.text;
request.fields['country'] = "UK";
request.fields['gender'] = this.gender;
String birthdayStr = "${birthday.year}-${birthday.month}-${birthday.day}";
request.fields['birthday'] = birthdayStr;
request.fields['phone'] = this.phone_no.text;
if (this.profilePicture != null) {
print('Profile picture available');
print(this.profilePicture.path);
request.files.add(
await MultipartFile.fromBytes(
'profile_picture',
await this.profilePicture.readAsBytes(), //this.profilePicture is a File
contentType: MediaType('image', 'jpeg'),
),
);
}
StreamedResponse resp = await request.send();
if (resp.statusCode < 200 || resp.statusCode >= 400) {
print('There was an error in making the SignUp Request');
print('Status code: ${resp.statusCode}');
} else {
Navigator.pop(context);
}
}

How do I assign specific users to a user-uploaded file so they can modify it/delete it (Django + Apache)

Im using django 1.10 + Apache in Linux.
I've created a small webapp to upload documents (with dropzone.js) and want to implement the ability for a user to specify who can view/modify/delete a specific file but i can't figure out a way how. I attempted using a ManyToManyField but maybe im not understading the Field itself correctly.
The "Document" model is this:
Model
class Document(models.Model):
file = models.FileField(upload_to = 'files/')
#validators=[validate_file_type])
uploaded_at = models.DateTimeField(auto_now_add = True)
extension = models.CharField(max_length = 30, blank = True)
thumbnail = models.ImageField(blank = True, null = True)
is_public = models.BooleanField(default = False)
accesible_by = models.ManyToManyField(User) #This is my attempt at doing this task.
def clean(self):
self.extension = self.file.name.split('/')[-1].split('.')[-1]
if self.extension == 'xlsx' or self.extension == 'xls':
self.thumbnail = 'xlsx.png'
elif self.extension == 'pptx' or self.extension == 'ppt':
self.thumbnail = 'pptx.png'
elif self.extension == 'docx' or self.extension == 'doc':
self.thumbnail = 'docx.png'
def delete(self, *args, **kwargs):
#delete file from /media/files
self.file.delete(save = False)
#call parent delete method.
super().delete(*args, **kwargs)
#Redirect to file list page.
def get_absolute_url(self):
return reverse('dashby-files:files')
def __str__(self):
return self.file.name.split('/')[-1]
class Meta():
ordering = ['-uploaded_at']
My View to handle the creation of documents:
View
class DocumentCreate(CreateView):
model = Document
fields = ['file', 'is_public']
def form_valid(self, form):
self.object = form.save(commit = False)
## I guess here i would Add the (self.request.user) to the accesible_by Field.
self.object.save()
data = {'status': 'success'}
response = JSONResponse(data, mimetype =
response_mimetype(self.request))
return response
Thanks in advance to anyone for any ideas or suggestions...
You have a model and a view that hopefully works for adding new documents, you still have a number of steps to go.
You'll need a place to assign users that can view/modify/delete your files. If you need to store access levels (view/delete...), your accessible_by will not suffice and you'll do well with a through table to add more information like access level.
You need to write views for various actions like view, delete... that users will request and here you ensure users have the right privileges. An implementation would be to get the request.user and the document id, look up if the user has the permission for what she's doing, return an http unauthorized exception or allow the action to proceed.
Edit: My question is about how can I assign user-permissions to each
individual file
If we're keeping this to access control from the django level, using the document model you already have, and you've taken some steps and for every document, you can assign users (accessible_by). Something like this can get you started:
from django.core.exceptions import PermissionDenied
def view_document(request, doc_pk):
doc = get_object_or_404(Document, pk=doc_pk)
if not doc.accessible_by.filter(username=request.user.username):
raise PermissionDenied
#perform rest of action
Or do you mean to use the permissions framework itself?

need help creating permalinks in google app engine

So I am trying to create a unique permalink each time that a person posts on my webpage and I want it to be relatively search engine friendly so I have made a little code to change the title to a good search engine title and it is working but then my handler cannot accept it. At least that is what I think is happening because the webpage just gives me a 404 error. The HTML works fine because when I redirect to a static page it all goes through. Here is the applicable code:
def post(self):
subject = self.request.get('subject')
content = self.request.get('content')
if subject and content:
p = Post(parent = blog_key(), subject = subject, content = content)
p.put()
id=str(p.key().id())
subject = str(subject)
subject = subject.replace(' ', '25fdsa67ggggsd5')
subject = ''.join(e for e in subject if e.isalnum())
subject = subject.replace('25fdsa67ggggsd5', '-')
subject = subject.lower()
url = '/blog/%s/%s' % (id, subject)
self.redirect('/blog/%s/%s' % (id, subject))
class PostPage(BlogHandler):
def get(self, post_id):
key = db.Key.from_path('PersonalPost', int(post_id), parent=blog_key())
post = db.get(key)
if not post:
self.error(404)
return
self.render("permalink.html", post = post)
class PersonalPost(db.Model):
subject = db.StringProperty(required = True)
content = db.TextProperty(required = True)
created = db.DateTimeProperty(auto_now_add = True)
last_modified = db.DateTimeProperty(auto_now = True)
user_id = db.StringProperty(required = True)
def render(self):
self._render_text = self.content.replace('\n', '<br>')
return render_str("post.html", p = self)
def blog_key(name = 'default'):
return db.Key.from_path('blogs', name)
app = webapp2.WSGIApplication([('/blog/([0-9]+)/([.*]+)', PostPage)]
And again it works when I just have it redirect to the main page and list them but not when I try to direct to the new SEO page.
UPDATE:
The test url I am using is setting
subject = "test-url"
id = "1234"
The app then directs me to www.url.com/blog/1234/test-url but it gives me a 404 error.
You define two groups in ('/blog/([0-9]+)/([.*]+) but your PostPage.get() only takes one.
Change it to def get(self, post_id, subject) or remove the second group ('/blog/([0-9]+)/[.*]+
I think you should have a look at the quotes on ur handler mapping, it seems inconsistent.
yours: app = webapp2.WSGIApplication([('/blog/([0-9]+)/([.*]+)', PostPage)]
try : app = webapp2.WSGIApplication(['/blog/([0-9]+)/([.*]+)', PostPage)]

Categories

Resources