upload image in forms Django - django

I am trying to upload image from form but whenever I submit everything got saved in database other than image field.But when I try to do samething from admin panel it works.
models.py
class Post(models.Model):
title = models.CharField(("Title"), max_length=100)
title_image = models.ImageField(
("Title Image"),
upload_to='static/Images/TitleImages/',
max_length=None,
blank = True,null = True)
Forms.py
class AddPostForm(ModelForm):
class Meta:
model = Post
fields = ['title','title_image']
Views.py
class AddPostView(LoginRequiredMixin,CreateView):
model = Post
template_name = 'MainSite/add_post.html'
fields = '__all__'
def dispatch(self, request, *args, **kwargs):
if request.user.is_anonymous:
messages.error(request,"You need to login to access this page")
return redirect('/')
elif request.user.is_superuser:
if request.method == "POST":
form = AddPostForm(request.POST)
if form.is_valid():
form.save()
messages.success(request,"POST added successfully")
return redirect('/')
else:
print("error")
else:
print("method is not post")
form = AddPostForm()
return render(request,'MainSite/add_post.html',{'form':form})
else :
messages.error(request,"You need to have superuser permission to access this page")
return redirect('/')
addpost.html
<form action= "" method="POST" enctype="multipart/form-data">
{% csrf_token %}
{{ form.media }}
{{ form|crispy}}
<button class="btn btn-primary profile-button" style = "width:150px;"type="submit" >Add Post</button></div>
</form>
my model have 2 things title and title_image but whenever I submit only title is saved and when I do through admin panel it works.
I dont know what I am doing wrong here any advice will be helpful.
Thanks in advance

You've to pass request.FILES in order to save files
if request.method == "POST":
form = AddPostForm(request.POST, request.FILES)
if form.is_valid():
form.save()
messages.success(request,"POST added successfully")
return redirect('/')

Related

how to pass the username to the member who fill a form?

i have a form, and i want to pass the user to it to see which logged in user filled it.
this is my forms.py
from .models import UserInfo
from django import forms
class InfoForm(forms.ModelForm):
class Meta:
model = UserInfo
fields = ('name', 'age', 'male', 'female', 'height', 'weight',
'BMI', 'BFP', 'phone', 'r_g_weight', 'physical_ready', 'fitness',
'workour_sports', 'others', 'goal_expression', 'body_change',
'noob','low_pro','semi_pro','pro','motivation_level','goal_block',
'change_time','past_sports','injury','work','work_time','wakeup_time',
'work_start_time','sleep_time','daily','hard_to_wake','ready_to_work',
'life_situation','weight_feel','daily_jobs','health_ready','workout_period',
'what_sport','where_sport','home_sport','weekly_time','sport_dislike','daily_food',
'food_quantity','hunger','vitamins','rejims','vegetables','goal_rec',
'stop','rec','heart','chest','chest_month','dizzy','bones','blood','other_reason')
and this is my view, i asked for the user with request.user , but the field in db always is empty for username.
def userForm(request):
if request.method == "POST":
form = InfoForm(request.POST)
if form.is_valid():
form.user = request.user
form.save()
return redirect('profile')
else:
form = InfoForm()
context = {
'form':form
}
return render(request, 'fitness/user_form.html', context)
so i have user in my models which has foreign key to my account
user = models.ForeignKey(Account,on_delete=models.CASCADE, null=True, blank=True)
and this is my template:
<div class="container">
<form action="{% url 'user-form' %}" method="POST" enctype="multipart/form-data">
{% csrf_token %}
{{form.as_p}}
<input type="submit" value="submit">
</form>
</div>
The problem lies in the way you are saving your form. You set the user attribute on the form, instead of the actual model object. The following should fix your issue
def userForm(request):
if request.method == "POST":
form = InfoForm(request.POST)
if form.is_valid():
# dont commit the object to the database as we need to set the user
object = form.save(commit=False)
# set the user
object.user = request.user
# finally save the object now that the user has been set
object.save()
return redirect('profile')
else:
form = InfoForm()
context = {
'form':form
}
return render(request, 'fitness/user_form.html', context)

Django Value Error "The view capstone.views.home didn't return an HttpResponse object. It returned None instead."

I'm taking data that the user puts into a form and saving it to the database in Django. When I submit the form, the value actually does save to the database. But I keep getting this error. Not sure how to fix it?
views.py
def home(request):
if request.method == "GET":
form_for_post = {'form': PostForm()}
return render(request, "capstone/home2.html", form_for_post)
else:
if request.method == "POST":
form = PostForm(request.POST)
if form.is_valid():
city = form.cleaned_data['city']
place = Location.objects.create(username=request.user, city=city,)
place.save()
else:
return render(request, "capstone/home2.html")
models.py
class User(AbstractUser):
pass
class Location(models.Model):
city = models.CharField(max_length=500)
username = models.ForeignKey('User', on_delete=models.CASCADE,
related_name='author', null=True, blank=True)
forms.py:
class PostForm(forms.Form):
city = forms.CharField(max_length=500)
Form in html:
<form method="POST">
{% csrf_token %}
<label for="city">City:</label><br>
<input type="text" id="city" name="city"><br>
<input type="submit" value="Submit">
</form>
By default if request is made it will be a get request so don't need to add if request.method == 'GET'
so do like this
def home(request):
form_for_post = {'form': PostForm()}
if request.method == "POST":
form = PostForm(request.POST)
if form.is_valid():
city = form.cleaned_data['city']
place = Location.objects.create(username=request.user, city=city,)
place.save()
return render(request,"your_page_after_form_successfully_submited")
return render(request, "capstone/home2.html",form_for_post)
def home(request):
if request.method == "POST":
form = PostForm(request.POST)
if form.is_valid():
city = form.cleaned_data['city']
place = Location.objects.create(username=request.user, city=city,)
place.save()
else:
return render(request, "capstone/home2.html",form)
form_for_post = {'form': PostForm()}
return render(request, "capstone/home2.html", form_for_post)
try this one

IntegrityError, NOT NULL constraint failed

I want to add tags to posts in my Django app.
I can add tags through the admin interface, but when I try to do it through the form I created, I get an IntegrityError.
I couldn't find the solution in the existing topics with the same error. I ran makemigrations and migrate.
From models.py:
class Post(models.Model):
title = models.CharField(null=False, blank=False)
text = models.TextField()
class Tag(models.Model):
post = models.ForeignKey('my_app.Post', on_delete=models.CASCADE, related_name='tags')
tag_text = models.CharField()
The view:
def post_add_tags(request, pk):
post= get_object_or_404(Post, pk=pk)
if request.method == "POST":
form = TagForm(request.POST)
if form.is_valid():
tag = form.save()
tag.post= post
tag.save()
return redirect("single_post_view", pk=post.pk)
else:
form = TagForm()
return render(request, "add_tags.html", {"form": form})
The form from forms.py:
class TagForm(forms.ModelForm):
class Meta:
model = Tag
fields = ["tag_text"]
The template:
<form method="POST"> {% csrf_token %}
{{ form.as_p }}
<button type="submit" class="save btn btn-default">Add tags</button>
</form>
The error:
IntegrityError at /post/4/add_tags/
NOT NULL constraint failed: my_app_tag.post_id
I'm using Django version 2.2, Python 3.6.8.
do not save form until you set all required fields, specially foreign keys :
def post_add_tags(request, pk):
post= get_object_or_404(Post, pk=pk)
if request.method == "POST":
form = TagForm(request.POST)
if form.is_valid():
tag = form.save(commit=False)
tag.post= post
tag.save()
return redirect("single_post_view", pk=post.pk)
else:
form = TagForm()
return render(request, "add_tags.html", {"form": form})

MultipleChoiceField form not displaying user's instance of form

I've implemented a MultipleChoiceField form with a CheckboxSelectMultiple. It works perfectly in that the form is displayed and user selected options are saved to the BaseServicesOffered model as desired. The problem is that when the user goes back to the form, the checkboxes that the user had previously selected/submitted are not selected -- they are all unchecked. I'd imagine that it's a problem with my views.py. Here is my code:
models.py
class BaseServicesOffered(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
service = models.CharField(max_length=255, default='', null=True, blank=True)
def __str__(self):
return self.user.username
forms.py
class BaseServicesOfferedForm(forms.ModelForm):
service = forms.MultipleChoiceField(required=False, widget=forms.CheckboxSelectMultiple)
def __init__(self, *args, **kwargs):
user = kwargs.pop('user') #this takes in the value of 'user', which is passed from the view function.
super(BaseServicesOfferedForm, self).__init__(*args, **kwargs)
self.fields['service'].choices = [(t.id, t.service) for t in AllServices.objects.filter(industrycode=user.userprofile.industry)]
class Meta:
exclude = ('user',)
model = BaseServicesOffered
views.py
#login_required(login_url="/accounts/login/")
def baseservicesoffered(request):
try:
base_services_offered = BaseServicesOffered.objects.create(user=request.user)
except:
pass
user = request.user
instance = get_object_or_404(BaseServicesOffered, user=user)
form = BaseServicesOfferedForm(request.POST or None, user=request.user, instance=instance)
if request.method == 'POST':
if form.is_valid():
instance = form.save(commit=False)
instance.user = request.user
service = form.cleaned_data['service']
services = [int(i) for i in service]
instance.service = services
instance.save()
return redirect('/accounts/profile/')
else:
context = {'form': form}
return render(request, 'accounts/setup8.html', context)
context = {'form': form}
return render(request, 'accounts/setup8.html', context)
setup8.html
<form id="post_form" method="post" action="" enctype="multipart/form-data">
{{ form.non_field_errors }}
{% csrf_token %}
{{ form.as_p }}
<div class="submitbutton">
<button type="submit">
SUBMIT
</button>
</div>
</form>
Update:
This is how you store a list of ints in the Charfield:
service = form.cleaned_data['service']
services = [int(i) for i in service] #converts list of strings to list of ints
instance.service = services
I've updated my code above with this.
multiple_choice = forms.MultipleChoiceField(
label=u"Select multiple",
choices=MY_CHOICES,
widget=forms.widgets.CheckboxSelectMultiple,
initial=(c[0] for c in MY_CHOICES)
)
You should set the inital parameter for the options to be checked for a particular user.

Upload Image with Django Model Form

I'm having difficulty uploading the following model with model form. I can upload fine in the admin but that's not all that useful for a project that limits admin access.
#Models.py
class Profile(models.Model):
name = models.CharField(max_length=128)
user = models.ForeignKey(User)
profile_pic = models.ImageField(upload_to='img/profile/%Y/%m/')
#views.py
def create_profile(request):
try:
profile = Profile.objects.get(user=request.user)
except:
pass
form = CreateProfileForm(request.POST or None, instance=profile)
if form.is_valid():
new = form.save(commit=False)
new.user = request.user
new.save()
return render_to_response('profile.html', locals(), context_instance=RequestContext(request))
#Profile.html
<form enctype="multipart/form-data" method="post">{% csrf_token %}
<tr><td>{{ form.as_p }}</td></tr>
<tr><td><button type="submit" class="btn">Submit</button></td></tr>
</form>
Note: All the other data in the form saves perfectly well, the photo does not upload at all. Thank you for your help!
You need to pass request.FILES to your form:
form = CreateProfileForm(request.POST, request.FILES, instance=profile)
Ref: Handling uploaded files with a model
Form initialization code have to be like this:
form = MemberSettingsForm(request.POST or None, request.FILES or None, instance=user)
I figured it out. It was a issue with my views.py. You need to set the request.method == POST to make sure you can still have the instance as a part of the form. Works perfectly though.
#Views.py
def create_profile(request):
try:
profile = Profile.objects.get(user=request.user)
except:
pass
if request.method == 'POST':
form = CreateProfileForm(request.POST, request.FILES)
if form.is_valid():
new = form.save(commit=False)
new.user = profile.user
new.save()
else:
form = CreateProfileForm(request.POST or None, instance=profile)
return render_to_response('profile.html', locals(), context_instance=RequestContext(request))
add this before save model instance :
new.profile_pic = request.FILES.get('profile_pic')