i am doing a copy cat with Need a minimal Django file upload example
i changed the view.py with my code to dump the csv file into sqlite database.
i have already created the table in default sqlite database.
import sqlite3
import csv
import sys
from django.shortcuts import render_to_response
from django.template import RequestContext
from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse
from myproject.myapp.models import Document
from myproject.myapp.forms import DocumentForm
def list(request):
# Handle file upload
if request.method == 'POST':
form = DocumentForm(request.POST, request.FILES)
if form.is_valid():
newdoc = Document(docfile = request.FILES['docfile'])
newdoc.save()
gfile= csv.reader(open(newdoc))
gon = sqlite3.connect("database.sqlite")
gon.text_factory = str
gon.execute("DELETE FROM abc where rowID > 0 ")
gon.executemany("insert into abc values (?, ?, ?, ?, ?)", gfile)
gon.commit()
gon.close()*
return HttpResponseRedirect(reverse('myproject.myapp.views.list'))
else:
form = DocumentForm() # A empty, unbound form
# Load documents for the list page
documents = Document.objects.all()
# Render list page with the documents and the form
return render_to_response(
'myapp/list.html',
{'documents': documents, 'form': form},
context_instance=RequestContext(request)
)
my code is starting from first introduction of gfile
Error # line 20 : Coercing to unicode : need string or buffer, Document Found
please help
You are passing Document instance to open. Instead you should pass the file, that was uploaded directly to csv.reader:
gfile = csv.reader(request.FILES['docfile'])
Related
I'm trying to write a simple IF statement on checking if a lastname in a database exists before a user hits the submit button to create a new record. Here is my code so far, I'm new to Django and Python so the help is appreciated.
I made a variable called lastname, the thought process here is when the user hits submit, it checks the database first before the commit to warn them with a popup if the lastname exists to prevent duplicate records. It would actually be really cool to have it when a person exits the field for it to run the script before they finish filling out the form to save time.
#views.py
from .models import StudentCheck
from django.shortcuts import render
from django.http import HttpResponse, Http404, HttpResponseRedirect
from forms.forms import NewStudentForm
def NewStudentFormCheckList (request):
if request.method == 'POST':
form = NewStudentForm(request.POST)
lastname = StudentCheck.lastname
if form.is_valid():
newstudent= form.save()
else:
form = NewStudentForm()
return render(request, 'forms/newstudentcheck_form.html', {'form': form})
Here is my test code to see if query is working correctly and i keep getting a error that the query set doesnt exists.
from .models import StudentCheck
from django.core.exceptions import ValidationError
from django.shortcuts import render
from django.http import HttpResponse, Http404, HttpResponseRedirect
from forms.forms import NewStudentForm
def NewStudentFormCheckList (request):
if request.method == 'POST':
form = NewStudentForm(request.POST)
lastname = StudentCheck.lastname
number_lastnames = StudentCheck.objects.get(lastname__exact=lastname)
if form.is_valid():
newstudent= form.save()
print (number_lastnames)
else:
form = NewStudentForm()
return render(request, 'forms/newstudentcheck_form.html', {'form': form})
You can get all the entries in the database which have a given value already set using the field lookup exact (see here for more informations).
In your case it'll be StudentCheck.objects.get(lastname__exact=yourvalue). This would give you a QuerySet, and if you want to know how many entries have the given last name, you have to use count() on this QuerySet to know how many entries it has.
You can use this solutions in two different places:
Directly in the view, when receiving the POST values.
In a custom validator, which would be used in the definition of the model (see here to know how to do)
I would recommend to use the second one, as it would be easier to provide custom information for the user on why it's data where not accepted.
Both of these methods requires the data to be passed to the server to be validated though. Otherwise you can define a view that would receive the lastname and return if it's present already in the database in some way (JSON for example), which would be called using Ajax when the user click on the submit button.
Edit:
As per request of OP, here's an example of the custom validator:
from django.core.exceptions import ValidationError
from .models import StudentCheck
def validate_lastname(value):
number_lastnames = StudentCheck.objects.get(lastname__exact=value)
if number_lastnames > 0:
raise ValidationError(
'%s already exists' % value,
)
Now you can use this custom validator with attribute validators, either in the definition of your model or inside the definition of your form like this: lastname = models.CharField(validators=[validate_lastname]).
Hope it helps!
I'm attempting to process an uploaded CSV file using Django. The main logic of how I go about doing this is expressed in both the models.py and views.py scripts. Once I've uploaded the file, I'm unable to process any of the content (in my views.py). Here are the two scripts, but if there's any more information I can provide, I'd be happy to.
In my models.py file, I have two classes, one for the document itself, and the other class for the fields in the file.
models.py:
from django.db import models
import os
class Document(models.Model):
docfile = models.FileField(upload_to='documents')
class DocumentEntry(models.Model):
document = models.ForeignKey(Document, on_delete=models.CASCADE)
field = models.CharField(max_length=250, default="TEST")
Next, in my views.py I get the file that was uploaded via the request.FILES['docfile'] and pass it to the handle_files() function. However, when I try to loop through the reader, I'm unable to access any of the elements in the file that was uploaded.
views.py:
from django.shortcuts import render
from django.conf import settings
from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse
import csv
from .models import Document, DocumentEntry
from .forms import UploadFileForm
def process_file(request):
# Handle file upload
if request.method == 'POST':
form = UploadFileForm(request.POST, request.FILES)
if form.is_valid():
handle_files(request.FILES['docfile'])
# Redirect to the document list after POST
return HttpResponseRedirect(reverse('process_files'))
else:
form = UploadFileForm() # A empty, unbound form
# Load documents for the list page
documents = Document.objects.all()
# Render list page with the documents and the form
return render(
request,
'upload/process_files.html',
{'documents': documents, 'form': form}
)
def handle_files(csv_file):
newdoc = Document(docfile=csv_file)
newdoc.save()
reader = csv.DictReader(open(csv_file))
for row in reader:
field = row['field']
entry = DocumentEntry(document=newdoc, field=field)
entry.save()
Updated
Here is full example of handler function:
def handle_files(csv_file):
newdoc = Document(docfile=csv_file)
newdoc.save()
with open(newdoc.docfile.name) as f:
reader = csv.DictReader(f)
for row in reader:
field = row['field']
entry = DocumentEntry(document=newdoc, field=field)
entry.save()
open() expects the path to the file, not the actual file data, which is contained in request.FILES['docfile'].
Replace:
reader = csv.DictReader(open(csv_file))
with:
import io
io_file = io.TextIOWrapper(csv_file.file)
reader = csv.DictReader(io_file)
Im working through Alex Pale's minimal django file upload example for django 1.8 -
https://github.com/axelpale/minimal-django-file-upload-example/tree/master/src/for_django_1-8/myproject/myproject/myapp
I know how to get the file extension in the form, but how can I get this in the view. I'm aware I can access the file thru -
docfile=request.FILES['docfile']
View -
from django.shortcuts import render_to_response
from django.template import RequestContext
from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse
from myproject.myapp.models import Document
from myproject.myapp.forms import DocumentForm
def list(request):
# Handle file upload
if request.method == 'POST':
form = DocumentForm(request.POST, request.FILES)
if form.is_valid():
docfile=request.FILES['docfile']
# Redirect to the document list after POST
return HttpResponseRedirect(reverse('myproject.myapp.views.list'))
else:
form = DocumentForm() # A empty, unbound form
# Load documents for the list page
documents = Document.objects.all()
# Render list page with the documents and the form
return render_to_response(
'list.html',
{'documents': documents, 'form': form},
context_instance=RequestContext(request)
)
Form -
from django import forms
class DocumentForm(forms.Form):
docfile = forms.FileField(
label='Select a file'
)
If you are asking for the extension try this:
>>> f = "this.that.ext"
>>> e = f.split(".")[-1]
>>> f
'this.that.ext'
>>> e
'ext'
>>>
You know how to get the complete filename. What you want is the last string after the "."
I want to make a application when the user upload the file, so get it to system, and execute the linux command like "xxd".
cSite---cSite---settings.py
| |__etc...
|
--myapp---
Here is my file upload codes.
views.py :
from django.shortcuts import render_to_response
from django.template import RequestContext
from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse
from myapp.models import Document
from myapp.forms import DocumentForm
def list(request):
# Handle file upload
if request.method == 'POST':
form = DocumentForm(request.POST, request.FILES)
if form.is_valid():
newdoc = Document(docfile = request.FILES['docfile'])
newdoc.save()
# Redirect to the document list after POST
return HttpResponseRedirect(reverse('myapp.views.list'))
else:
form = DocumentForm() # A empty, unbound form
# Load documents for the list page
documents = Document.objects.all()
# Render list page with the documents and the form
return render_to_response(
'list.html',
{'documents': documents, 'form': form},
context_instance=RequestContext(request)
)
models.py :
from django.db import models
class Document(models.Model):
docfile = models.FileField(upload_to='documents/%Y/%m/%d')
As you know, this code is widespreaded simple file upload form.
Now, here is my trouble.
Want to use the salt when I save the file
(Can I use the "Keeping Original Filename for FileField in Django"? and if I can, how to apply this?
I don't know what is representing the file path variable in FileField on ./views.py/ It always contain the error. (The command must be executed at the right after same time of file uploaded in user view.)
On the 'panel' page, I have a choice field with a list of uploaded documents or 'bots' as I usually refer to them. This list only displays 'bots' that have been uploaded by the current user.
panel\forms.py
from django import forms
import os
from upload.models import Document
#### RETRIEVE LIST OF BOTS UPLOADED BY CURRENT USER ####
def get_files(user):
bots = Document.objects.filter(user=user.id)
file_list = []
for b in bots:
file_list.append((b.id,b.docfile))
return file_list
class botForm(forms.Form):
def __init__(self, user, *args, **kwargs):
super(botForm, self).__init__(*args, **kwargs)
self.fields['bot'] = forms.ChoiceField(choices=get_files(user))
This works fine and displays a list of all the users bots. The problem arises when I try to pass these values over to the 'game' page and access them here.
game\views.py
from django.shortcuts import render_to_response
from django.template import RequestContext
from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse
from game.models import game
from game.forms import GameForm
from upload.models import Document
from panel.forms import botForm
import league
def RPS(request):
if request.method == 'POST': # If the request is a POST method...
if 'PanelPlay' in request.POST:
panel = botForm(request.POST)
if panel.is_valid():
print panel.cleaned_data['bot']
elif 'GamePlay' in request.POST:
form = GameForm(request.POST) # A form bound to the POST data
if form.is_valid(): # All validation rules pass
leagueOuput = []
leagueOutput = league.run(form.cleaned_data['bot1'],form.cleaned_data['bot2'])
newGame = game()
newGame.bot1 = leagueOutput[0]
newGame.bot2 = leagueOutput[1]
newGame.bot1wins = leagueOutput[2]
newGame.bot2wins = leagueOutput[3]
newGame.save()
return HttpResponseRedirect(reverse('game.views.RPS')) # Redirect after POST
form = GameForm() # An unbound form
results = game.objects.all() # Load messages for the list page
return render_to_response('game.html', {'results': results, 'form': form}, context_instance=RequestContext(request))
When attempting to access and validate the panel data, I get the following error.
'QueryDict' object has no attribute 'id'
Referring to this specific line.
bots = Document.objects.filter(user=user.id)
I have found and read about a number of similar issues but I can't seem to carry over their solutions to my own project.
Thanks in advance for any and all help.
When you are constructing the botForm, you're passing request.POST (a QueryDict) as the user parameter. Did you mean
panel = botForm(request.user, data=request.POST)
?
(assuming you're using django authentification).