I am working on an app that has a section with with a file upload form for .txt fiels. I would like for the current user that is uploading the file to be added along with the file and the file name. Currently, I can do this successfully in the admin section but I just cant get it to save via the form itself. Any Ideas?
Here are the models:
class UploadedTextFile(models.Model):
file = models.FileField(upload_to="textfiles")
filename = models.CharField(max_length = 50)
username = models.ForeignKey(User, blank=True, null=True)
class UploadedTextFileForm(ModelForm):
class Meta:
model = UploadedTextFile
fields = ['file', 'filename']
Here is my view:
def inputtest(request):
#response for file being submited
if request.method == "POST":
form = UploadedTextFileForm(request.POST)
if form.is_valid():
new_form = form.save(commit=False)
new_form.username = request.user
new_form.save()
return render(request, 'about.html')
inputtest = UploadedTextFileForm()
return render(request, 'failed.html', {'inputtest': inputtest})
else:
inputtest = UploadedTextFileForm()
return render(request, 'inputtest.html', {'inputtest': inputtest})
Here is my html:
{% extends 'base.html' %}
{% block content %}
<form method="post">{% csrf_token %}
{{ inputtest.as_p }}
<input type="submit" value="Submit" />
</form>
{% endblock content %}
Doing it in the view (as you've shown) is the right way to do this. Most likely you're having problems because you've left username as a field on the form, and because the FK model field doesn't have blank=True set the form requires the field to be provided. You should explicitly declare just the subset fields that you want to accept user input for in the form's Meta class.
class UploadedTextFileForm(ModelForm):
class Meta:
model = UploadedTextFile
fields = ['file', 'filename']
I am not sure why you're rendering a different template when the form is not valid, but no matter what you're not providing the form object in the context. This means that you'll never see any errors the form detects, which is probably what's happening with this code - you're not seeing the error that username is not provided.
Related
I am trying to create a django website similar to that of Udemy or Coursera. I am trying to implement a feature that lets users add courses.
Here is my view for adding the course:
def create_course(request):
form = CreateCourseForm()
if request.method == 'POST':
form = CreateCourseForm(request.POST)
if form.is_valid():
new_course = form.save(commit=False)
new_course.instructor = request.user
new_course.save()
return redirect('home')
return render(request, 'courses/create.html',{'form':form})
Here is my form:
class CreateCourseForm(forms.ModelForm):
class Meta:
model = Course
fields = ('name','video','description','category',)
My course model:
class Course(models.Model):
name = models.CharField(max_length=200)
instructor = models.ForeignKey(User, on_delete=models.CASCADE)
video = models.FileField(upload_to='videos/')
description = models.TextField()
category = models.ForeignKey(Category, on_delete=models.CASCADE)
def __str__(self):
return self.name
And finally my web form:
{% extends "base.html" %}
{% load crispy_forms_tags %}
{% block content %}
<h1>Create a Course</h1>
<hr>
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form|crispy }}
<button class="btn btn-sm btn-outline-primary" type="submit">Create Course</button>
</form>
{% endblock %}
The issue i am facing is that when i try to create a course, the video field shows an error "This field is required" even when I have uploaded a video.
I tried researching a bit and found out that adding enctype="multipart/form-data" to the form was required, but even adding that didn't solve my problem
Can anyone help me here?
You need to pass request.POST and request.FILES to the form, so:
def create_course(request):
form = CreateCourseForm()
if request.method == 'POST':
# add request.FILES ↓
form = CreateCourseForm(request.POST, request.FILES)
# …
return render(request, 'courses/create.html',{'form':form})
If you only pass request.POST, you are only passing the items of the form that are not file uploads. This then will indeed add an error to the form fields of these files, saying that the form requires data for these fields.
as willem told you have to request file in you form like this
def create_course(request):
form = CreateCourseForm()
if request.method == 'POST':
form = CreateCourseForm(request.POST, request.FILES)
if form.is_valid():
new_course = form.save(commit=False)
new_course.instructor = request.user
new_course.save()
return redirect('home')
return render(request, 'courses/create.html',{'form':form})
but i think you have to know one more you don't have to pass / in while telling django where to upload that file
class Course(models.Model):
name = models.CharField(max_length=200)
instructor = models.ForeignKey(User, on_delete=models.CASCADE)
video = models.FileField(upload_to='videos')
description = models.TextField()
category = models.ForeignKey(Category, on_delete=models.CASCADE)
def __str__(self):
return self.name
offcourse willem answer will solve your problem but you will see in your media folder a new folder name videos/ got created where you file is storing instead of your actual folder becuase you are telling django to upload that file in folder name vedios/ and if django doesn't find that folder it will create that folder with that name and then stat uploading it
I am trying to save a file and some other details in django using forms.
And I only want it to save a CharField and a FileField but not the country field.
For country field I want it to take its value through a post request.
But the form isn't saving. The errors says "data didn't validate".
Also this method works fine if I don't use a FileField.
models.py
class Simple(models.Model):
name = models.CharField(max_length=100)
city = models.FileField(upload_to='marksheet')
country = models.CharField(max_length=100)
forms.py
class SimpForm(forms.ModelForm):
class Meta:
model = Simple
fields = ['name','city']
A snippet from upload.html
<form action="upload" method="POST" enctype="multipart/form-data">
{% csrf_token %}
<label>Test input</label>
<input type="text" name="country">
{{form.name}}
{{form.city}}
<button type="submit">Submit</button>
</form>
views.py
def upload(request):
if request.method == 'POST':
a = request.POST.get('country')
form = SimpForm(request.POST,request.FILES)
if form.is_valid():
post = form.save(commit=False)
post.country = a
post.save()
return HttpResponse('saved')
else:
return HttpResponse('ERROR SAVING')
else:
form = SimpForm()
return render(request,'upload.html',{'form':form})
You are not passing request.FILES in your form. You should pass it like this:
form = SimpForm(request.POST, request.FILES)
More information on file uploads can be found in documentation.
I'm trying to get a simple form working. Oddly, other forms I wrote in this app are working fine, but this one wont show the fields. Can anyone tell me what I'm missing? Here are the files
views.py:
def newnote(request, record_id):
if request.method == 'POST':
form = NoteForm(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect('/tracker/all/')
else:
form = NoteForm()
return render(request, 'tracker/noteform.html', {'form': form})
models.py
class Note(models.Model):
record = models.ForeignKey(Record, on_delete=models.CASCADE)
note_text = models.CharField('Notes', max_length=2000)
note_date = models.DateField('Date Entered')
forms.py
class NoteForm(forms.Form):
class Meta:
model = Note
fields = ['note_text',
'note_date'
]
template (noteform.html)
<form action="/tracker/newnote/" method="post">
<div id="fields">
{% csrf_token %}
{{ form }}
<input type="submit" value="Submit" />
</div>
</form>
One other note, I have commented out the div id called "fields", to rule out CSS as the issue.
Your form is based on form.Form, which doesn't know anything about models, doesn't expect a Meta class, and expects all its fields to be declared manually - since you have not declared any fields, nothing will show on the template.
It should inherit forms.ModelForm instead.
I have been going through the Django forms 'tutorial'. Once I had read through the tutorial, I tried modifying it to suit my needs and customize it to learn it Django forms well. I discovered whenever I modified the form, the website would not update. I assume its an error with my code, but I have not been able to find it.
# views.py
def contact(request):
# if this is a POST request we need to process the form data
if request.method == 'POST':
# create a form instance and populate it with data from the request:
form = ContactForm(request.POST)
# check whether it's valid:
if form.is_valid():
# process the data in form.cleaned_data as required
# ...
# redirect to a new URL:
return HttpResponseRedirect('/message_recived/')
# forms.py
from django import forms
class ContactForm(forms.Form):
name = forms.CharField(label='Name', max_length=100)
email = forms.EmailField(label='Email', max_length=100)
message = forms.CharField(label='Message', max_length=500)
# models.py
from django.db import models
class Contact(models.Model):
name = models.CharField(max_length=100)
email = models.CharField(max_length=100)
message = models.CharField(max_length=500)
and here is the contact.html template:
#contact.html
{% extends "BlogHome/headerAndFooter.html" %}
{% block content %}
<script>
document.title = "Pike Dzurny - Contact"
</script>
<form action="/message_recived/" method="post">
{% csrf_token %}
{{ form }}
<input type="submit" value="Submit" />
</form>
{% endblock %}
Did I do something wrong? I have tried clearing my browsers cache, using a new browser, and obviously refreshing it.
Looks like your forget to render response inside your view.
Also you need to include form into context to render template right.
Try to change view as follow:
def contact(request):
# if this is a POST request we need to process the form data
if request.method == 'POST':
# create a form instance and populate it with data from the request:
form = ContactForm(request.POST)
# check whether it's valid:
if form.is_valid():
# process the data in form.cleaned_data as required
# ...
# redirect to a new URL:
return HttpResponseRedirect('/message_recived/')
else:
form = ContactForm()
return render(request, 'contact.html', {'form': form})
I am building a Django site to share code for Python games, but I'm running into trouble associating each game with a specific user. I'm trying to do this by using the user as the ForeignKey, which I think is the right approach, but I can't get the user to actually get inserted into the database without using some weird hack (like passing the user as a string into a hidden user field, which is totally insecure and causes other issues.)
My Game class looks like this:
class Game(models.Model):
user = models.ForeignKey(User, blank=True)
title = models.CharField(max_length=256)
image = models.ImageField(upload_to='games')
description = models.CharField(max_length=256)
requirements = models.CharField(max_length=256)
code = models.CharField(max_length=256000)
def __unicode__(self):
return self.title
The form for adding a game:
class GameForm(forms.ModelForm):
image = forms.ImageField(required=False)
code = forms.CharField(widget=PagedownWidget(show_preview=True))
class Meta:
model = Game
fields = ('user','title','image','description','requirements','code')
User.game = property(lambda u: Game.objects.get_or_create(user=u)[0])
I create a custom version of this form in my addgame.html template:
<form action="/userprofile/addGame/" method="post">{% csrf_token %}
{% for field in form.visible_fields %}
<div class="fieldWrapper">
{{ field.errors }}
{{ field.label_tag }}
<br>
{{ field }}
<br><br>
</div>
{% endfor %}
<input type="submit" value="Save">
</form>
My View looks like this:
#login_required
def add_game(request):
user = request.user
error_message = None
if request.method == 'POST':
form = GameForm(request.POST)
if form.is_valid():
form = form.save(commit=False)
form.uploader = request.user
form.save()
return HttpResponseRedirect('/userprofile')
else:
error_message = "Invalid Input"
else:
form = GameForm()
args = {}
args.update(csrf(request))
args['user'] = user
args['form'] = form
args['error_message'] = error_message
return render_to_response('addgame.html', args)
However, I get the following error:
Cannot assign None: "Game.user" does not allow null values.
I realize that a User instance has not been passed into the form, thus I am getting a 'shouldn't be null' error, but I have no idea how to properly pass in the User instance to the form. I've looked at several questions on this exact issue, such as this, but I still haven't been able to get User successfully passed in to the form.
Problem 1:
form.uploader = request.user
Should be:
form.user = request.user
I dont see uploader attribute in your Game model
Problem 2:
In the GameForm Meta class, the following line should not include a user field:
fields = ('title','image','description','requirements','code')