Django image uploading - python

I have a problem with image uploading. For now, chosen image file is not copied to destination directory and path to this file is not added to database.
I'm giving my code below:
models.py:
from django.db import models
from django.contrib.auth.models import User
class UserProfile(models.Model):
user = models.OneToOneField(User)
avatar = models.ImageField(upload_to="avatar/")
form.py
class ProfileEditionForm(ModelForm):
class Meta:
model = UserProfile
exclude = ('user')
view.py:
def index(request):
if request.user.is_authenticated():
user = User.objects.get(pk=request.user.id)
if request.method == "POST":
form = ProfileEditionForm(request.POST, request.FILES, instance=user)
if form.is_valid():
form.save()
#return HttpResponseRedirect(reverse('profile_edit'))
else:
form = ProfileEditionForm(instance=user)
return direct_to_template(request, 'profile_edit.html', { 'form' : form })
else:
return HttpResponseRedirect(reverse('main_page'))
Thanks in advance for help.

https://docs.djangoproject.com/en/dev/topics/http/file-uploads/
your form should have the enctype="multipart/form-data" or request.FILES won't have any data stream associated

your ModelForm is bound to UserProfile model, but your are instantiating it with instance=user.
PS: request.user is User.objects.get(pk=request.user.id)

Related

Django: Create a Model instance with the build-in User Model fields

So i have a Car model. And every car is submitted is assigned to a user. Also every user has his own dashboard where they can submit cars (Only for logged in users).
from django.db import models
from django.contrib.auth.models import User
class Car(models.Model):
user = models.ForeignKey(User,on_delete=models.CASCADE,null=True)
model_car= models.CharField(max_length=200)
description = models.TextField()
car_image = models.ImageField(null=True, blank=True)
date_created = models.DateTimeField(auto_now_add=True)
This is my forms.py where i create cars. And then i render this form to the frontend.
from django import forms
from django.forms import ModelForm
from tasks.models import Car
class CreateCarForm(ModelForm):
class Meta:
model=Car
fields='__all__'
exclude = ('user',)
Views.py
def create_car(request):
form = CreateCarForm()
if request.method=="POST":
form = CreateCarForm(request.POST,request.FILES)
if form.is_valid():
form.save()
messages.success(request,'Car was Created')
return redirect('create_car')
context={'form':form}
return render(request, 'dashboard/create_car.html',context)
Now it just creates a car instance, but with no selected user. What i would like to do is to create this Car instance, but in the user field, to auto assign the current logged-in user username.
How can i achieve this?
You can set the .user instance of the Car instance wrapped in the CreateCarForm:
from django.contrib.auth.decorators import login_required
#login_required
def create_car(request):
form = CreateCarForm()
if request.method=='POST':
form = CreateCarForm(request.POST,request.FILES)
if form.is_valid():
form.instance.user = request.user
form.save()
messages.success(request,'Car was Created')
return redirect('create_car')
context={'form':form}
return render(request, 'dashboard/create_car.html', context)

Django ModelForm does not save in database

I am trying to make a simple to-do list in Django that each user could have their own task list so when they logged in they add a task and its save for themselves and the list only display their own tasks, but when I try to add a task from the template's form it won't save but when I add task manually from admin panel it work.
my models.py
from django.db import models
from django.contrib.auth.models import User
class Tasks(models.Model):
user = models.ForeignKey(User, null=True,on_delete=models.CASCADE)
title = models.CharField(max_length=200)
check = models.BooleanField(default = False)
date = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.title
forms.py
from django import forms
from django.forms import ModelForm
from .models import *
class TaskForm(forms.ModelForm):
class Meta:
model = Tasks
fields = '__all__'
views.py:
from django.shortcuts import render, redirect
from django.contrib.auth.decorators import login_required
from .forms import *
from .models import Tasks
#login_required(login_url = 'login')
def tasks(request):
tasks = Tasks.objects.filter(user = request.user)
context = { 'tasks': tasks }
return render(request,'ToDo/list.html',context)
#login_required(login_url = 'login')
def add_task(request):
form = TaskForm()
if request.method == 'POST':
form = TaskForm(request.POST)
if form.is_valid():
form.save(commit=False)
form.user = request.user
form.save()
return redirect('/')
context = {'form' : form}
return render(request,'ToDo/add.html',context)
where is the problem?
You assign the user to the .user attribute of the form, not of the .instance wrapped in the form. You thus should alter the instance with:
#login_required(login_url = 'login')
def add_task(request):
if request.method == 'POST':
form = TaskForm(request.POST, request.FILES)
if form.is_valid():
form.instance.user = request.user
form.save()
return redirect('/')
else:
form = TaskForm()
return render(request, 'ToDo/add.html', {'form' : form})
You should furthermore only redirect in case of a successful POST request: in case the POST request is not successful, the form can render the error messages, and thus will inform the user what the problem is.
Furthermore you make the user field non-editable:
from django.conf import settings
class Tasks(models.Model):
user = models.ForeignKey(
settings.AUTH_USER_MODEL,
editable=False,
on_delete=models.CASCADE
)
title = models.CharField(max_length=200)
check = models.BooleanField(default = False)
date = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.title
Note: It is normally better to make use of the settings.AUTH_USER_MODEL [Django-doc] to refer to the user model, than to use the User model [Django-doc] directly. For more information you can see the referencing the User model section of the documentation.

Django ModelForm ignores the data supplied via form and saves the superuser name in the table

I'm new at using Django forms (Django altogether), and on my first form, I have encountered this error. No matter what data I post via the form it saves the superuser name in all the fields.
Here are the files,
forms.py
from django.forms import ModelForm
from .models import *
class NewCustomer(ModelForm):
class Meta:
model = Customer
fields = ('name', 'mobile_number', 'email', 'address')
Views.py
from django.shortcuts import render, get_object_or_404, redirect
from .models import *
from .forms import *
# Create your views here.
def customers(request):
customers = Customer.objects.all().order_by('id')
return render(request, "customers.html", {'customers': customers, 'custactive': "active"})
def customer_details(request, pk):
customer = get_object_or_404(Customer, pk=pk)
return render(request, "customer_details.html", {'customer': customer})
def new_customer(request):
if request.method == 'POST':
form = NewCustomer(request.POST)
if form.is_valid():
customer = form.save(commit=False)
customer.name = request.user
customer.mobile_number = request.user
customer.email = request.user
customer.address = request.user
customer.save()
return redirect ('customers')
else:
form = NewCustomer()
return render(request, "new_customer.html", {'form': form})
Can someone tell me what's wrong with the code? Understandably I need to save new data that I supply with the form.
Really appreciate your help...
The problem is that you need to tell the form which fields to get from User object.
Now if you have extended the User model and have name, mobile_number, address specified, you need to modify your code.
def new_customer(request):
if request.method == 'POST':
form = NewCustomer(request.POST)
if form.is_valid():
customer = form.save(commit=False)
customer.name = request.user.name
customer.mobile_number = request.user.mobile_number
customer.email = request.user.email
customer.address = request.user.address
customer.save()
return redirect ('customers')
The reason whz superuser's name is saved in all fields is because all models have their str method, which tells python what to print out if object itself is used.

Forms and views for custom User model with extra parameters [django 2.1]

Im trying to create a form that would allow me to add a profile picture to the custom User object. I know that there is OneToOne method, although I want it to be stored directly in User.
You need to extend default User Model like this:
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
"""Add more fields to default user model."""
profile_pic = models.ImageField(upload_to='profile_pics', blank=True, null=True)
Now you need to edit your settings.py to make your custom User model the default auth model. Add this line in your settings.py:
AUTH_USER_MODEL = 'myApp.User'
myApp is the name of app in whose models.py your created your Custom User Model.
And that's all, now the default auth model is your custom model User which is exactly the same as the Django default auth model except it has an additional field profile_pic to store an image.
Form to add picture should be like this:
class profilepictureForm(forms.ModelForm):
"""Form to add profile picture to User model."""
class Meta:
"""Meta class for profilepictureForm."""
model = User
fields = ('profile_pic', )
And in your views you should use this form like this:
def add_profile_picture(request):
if request.method == 'POST':
form = profilepictureForm(request.POST, request.FILES, instance=request.user)
if form.is_valid():
form.save()
return HttpResponseRedirect('/success/url/')
else:
form = profilepictureForm(instance=request.user)
return render(request, 'userpanel/profilepicture.html', {'form': form})
Have a look on below code
from django.http import HttpResponseRedirect
from django.shortcuts import render
from .forms import UploadFileForm
# Imaginary function to handle an uploaded file.
from somewhere import handle_uploaded_file
def upload_file(request):
if request.method == 'POST':
form = UploadFileForm(request.POST, request.FILES)
if form.is_valid():
handle_uploaded_file(request.FILES['file'])
return HttpResponseRedirect('/success/url/')
else:
form = UploadFileForm()
return render(request, 'upload.html', {'form': form})
For more information please check https://docs.djangoproject.com/en/dev/topics/http/file-uploads/

How to submit data entered in the forms directly into database?

I have designed a form in django wherein there are 3 fields "Title","Body" & "Tagline". So my query is that when i press submit button after filling up the data that data should be directly inserted into my "notes" database.
Models.py
from django.db import models
class pim(models.Model):
Title = models.CharField(max_length=40)
Body = models.CharField(max_length=40)
TagLine = models.CharField(max_length=40)
Views.py
from django.shortcuts import render_to_response
from django.http import HttpResponse, Http404
def Notes_create(request):
return render_to_response('notesform.html',locals())
You'll need to create a modelform for your pim model:
class pimForm(ModelForm):
class Meta:
model = pim
And your view will have to display the form and handle it when the request type is a POST:
def new(request):
if request.method == 'POST':
form = pimForm(request.POST)
if form.is_valid():
form.save()
return redirect(reverse('your.pim.detail.view', args=[pim.pk]))
else:
form = pimForm()
return render_to_response('notesform.html', {'form': form}, context_instance=RequestContext(request))
Something like that should work

Categories