Reputation: 45
I need to tie the user to their post but 'author' is not included in the fields of the video upload form so I can't access the field when I save the form.
When I add 'author' to the fields it gives a drop down box. (users shouldn't be able to post as anyone but themselves) I tried just listing the fields individually like so {{form.title}}
to keep the author field but not show it to the user, it showed anyway.
In the 'author' field of the VideoPost model I've tried changing out the null=True
for these variants on default default=None, default=0, default='None', default=User, default=User.id
where User = get_user_model()
When I used default='None'
the author dropdown box had the current users name in it, but still allowed a choice, when I tried to post it I got
ValueError: invalid literal for int() with base 10: 'None'
Also, in the views.py, I tried form = VideoPostForm(request.user,request.POST or None, request.FILES or None)
and got CustomUser object has no .get() attribute
and that was caused by form.save()
I feel like this might be obvious to someone else but I've been staring at this code for a while now to figure it out.(a couple hours a day doing research and gaining better understanding as to how all of the things I'm doing actually work 'under the hood', I worked on other parts while trying to figure this out because, development speed matters and I could actually figure the other stuff out)
forms.py
class VideoPostForm(forms.ModelForm):
class Meta:
model = VideoPost
fields = ['author','title', 'description', 'file']
views.py
def upload_video(request):
form = VideoPostForm(request.POST or None, request.FILES or None)
if form.is_valid():
form.save(commit=False)
VideoPost.author = request.user
form.save()
return redirect('home')
else:
form = VideoPostForm()
return render(request, 'upload_video.html', {'form': form})
models.py
class VideoPost(models.Model):
objects = models.Manager()
author = models.ForeignKey(User, related_name='video_post', on_delete=models.CASCADE, null=True)
title = models.CharField(max_length=50, null=True, blank=True)
published_date = models.DateTimeField(auto_now_add=True)
description = models.TextField()
validate_file = FileValidator(max_size=52428800)
file = models.FileField(upload_to='videos/', validators=[validate_file])
def __str__(self):
return 'Post by {}'.format(self.author)
template (excluding author field)
<h1>Create Post Page</h1>
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
<p> <!-- Normally the fields would be form.as_p -->
{{ form.title }}
{{ form.description }}
{{ form.file }}</p>
<button type="submit">Submit New Post</button>
</form>
Upvotes: 0
Views: 491
Reputation: 566
The views.py
is very close. The form.save() method returns an instance of VideoPost. You can then set the author to the current user directly to the new video post object that was created by the form. See code sample below.
views.py
def upload_video(request):
if request.method == "POST":
form = VideoPostForm(request.POST, request.FILES or None)
if form.is_valid():
new_videopost = form.save()
new_videopost.author = request.user
new_videopost.save()
return redirect('home')
else:
form = VideoPostForm()
return render(request, 'upload_video.html', {'form': form})
Upvotes: 1