Form is not being saved in Django admin page - python

I have faced a problem in my Django project where my form is not being saved as a new listing in my model(listing) and is not even showing on Django's admin page.
my models.py :
class listing(models.Model):
title = models.CharField(max_length=64)
describtion = models.CharField(max_length=300)
bid = models.FloatField()
category = models.ForeignKey(categories, default=1, verbose_name="Category",
on_delete=models.SET_DEFAULT)
user = models.ForeignKey(User,default='', verbose_name="User", on_delete=models.SET_DEFAULT)
image = models.CharField(max_length=400)
def __str__(self):
return f"{self.title} "
create a new listing form :
class create(ModelForm):
class Meta:
model = listing
fields = [ 'title', 'describtion','bid','category','image']
views.py :
def CreateListing(request):
user = request.user
if request.method == "POST":
form = create(request.POST, instance=user)
if form.is_valid():
new_listing = form.save()
new_listing.user = request.user
new_listing.save()
return render(request, "auctions/listing.html")
else:
return render(request, "auctions/Create.html",{
"form": create
})
Ps: I have no problem with my urls.py

You need to set the user before you can save this to the database:
def CreateListing(request):
user = request.user
if request.method == "POST":
form = create(request.POST, instance=user)
if form.is_valid():
form.instance.user = user
form.save()
return redirect('%name-of-some-view')
else:
form = create(instance=user)
return render(request, "auctions/Create.html",{
'form': form
})
Note: You can limit views to a view to authenticated users with the
#login_required decorator [Django-doc].
Note: In case of a successful POST request, you should make a redirect
[Django-doc]
to implement the Post/Redirect/Get pattern [wiki].
This avoids that you make the same POST request when the user refreshes the
browser.

Related

How to get the current logged in user? Django models

I want to get the current logged in user to this CreateForm form. Below Im giving my current code, here request.user is not giving me error
ValueError at /create-post/
Cannot assign "<SimpleLazyObject: <User: testuser>>": "Post.author" must be a "Author" instance.
models.py
class Author(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
rate = models.IntegerField(default=0)
class Post(models.Model):
title = models.CharField(max_length= 50)
overview = models.TextField()
body_text = RichTextUploadingField(null = True)
time_upload = models.DateTimeField(auto_now_add=True)
author = models.ForeignKey(Author, related_name='author', on_delete=models.CASCADE)
thumbnail = models.ImageField(upload_to = 'thumbnails')
publish = models.BooleanField()
categories = models.ManyToManyField(Categories)
read = models.IntegerField(default=0)
slug = models.SlugField(null= True, blank= True)
Forms.py
class CreateForm(ModelForm):
class Meta:
model = Post
fields = [
'title',
'overview',
'body_text',
'thumbnail',
'categories',
'publish',
]
Views.py
def create_post(request):
if request.method == 'POST':
form = CreateForm(request.POST, request.FILES)
if form.is_valid:
post = form.save(commit=False)
post.author= request.user
post.save()
return render(request, 'index.html')
else:
form = CreateForm()
return render(request, 'create_post.html', {'form': form})
As the error says, post.author expects an Author object, not the user. You thus retrieve this with:
from django.contrib.auth.decorators import login_required
#login_required
def create_post(request):
if request.method == 'POST':
form = CreateForm(request.POST, request.FILES)
if form.is_valid():
form.instance.author= request.user.author
form.save()
return render(request, 'index.html')
else:
form = CreateForm()
return render(request, 'create_post.html', {'form': form})
You should also call the is_valid() method [Django-doc], so form.is_valid().
Note: You can limit views to a view to authenticated users with the
#login_required decorator [Django-doc].
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.
The author field on your Post model is a foreign key to Author model, and not user. You could replace post.author = request.user with:
if request.user.author:
post.author = request.user.author
else:
post.author = Author.objects.create(user=request.user)
The answer from Willem works if an Author instance was already created for the User, but will throw an exception if there's no Author object associated with that user.

django: get() returned more than one Freelancers -- it returned 3

i am trying to assign a freelancer to a particular gig but it shows get() returned more than one Freelancers -- it returned 3!. I have tried getting the logged in freelancer to is trying to create the git like this freelancer = get_object_or_404(Freelancers, user=user) and before i save the form i assign the value like this new_form.creator = freelancer .
views.py
#login_required
def create_gig(request):
user = request.user
freelancer = get_object_or_404(Freelancers, user=user)
if request.method == "POST":
form = CreateGig(request.POST, request.FILES)
if form.is_valid():
new_form = form.save(commit=False)
new_form.user = request.user
new_form.creator = freelancer
new_form.slug = slugify(new_form.title)
new_form.save()
messages.success(request, f'Gig Created Successfully, Would be Live Soon')
return redirect('freelance:listings')
else:
form = CreateGig()
context = {
'form': form
}
return render(request, 'freelance/create.html', context)
models.py
class Gigs(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='gig_user')
creator = models.ForeignKey(Freelancers, on_delete=models.CASCADE, related_name='gig_creator')
title = models.CharField(max_length=1000, null=True, blank=True, verbose_name="Enter what you will do", default=" I will ")
In my code, it is getting a logged-in user instance and then creating the gig by assigning the freelancer to the created form.
#login_required
def create_gig(request):
freelancer = Freelancers.objects.get(user = request.user )
if request.method == "POST":
form = CreateGig(request.POST, request.FILES)
if form.is_valid():
new_form = form.save(commit=False)
new_form.creator = freelancer
new_form.slug = slugify(new_form.title)
new_form.save()
messages.success(request, f'Gig Created Successfully, Would be Live Soon')
return redirect('freelance:listings')
else:
form = CreateGig()
context = {
'form': form
}
return render(request, 'freelance/create.html', context)
You also don't need this line in your view:
new_form.user = request.user

Django - Error received when anonymous user submits form

In one of my views I have a form where when a user logs in and submits the form, it works fine.
However, when an anonymous user submits the form I get the following error:
Cannot assign "<SimpleLazyObject: <django.contrib.auth.models.AnonymousUser object at 0x1052fd3a0>>": "User_Inquiries.user" must be a "CustomUser" instance.
This form needs to be submitted whether a user is anonymous or logged in.
What do I need to do in order to resolve this issue?
Code below.
Any help is gladly appreciated. Thanks!
views.py
def account_view_contact(request):
form = ContactUsForm(request.POST or None, request.FILES or None,)
user_profile = User_Inquiries.objects.all()
user_profile = User_Info.objects.all()
user = request.user
if request.method == "POST": # checking if request is POST or Not
# if its a post request, then its checking if the form is valid or not
if form.is_valid():
contact_instance = form.save(commit=False) # "this will return the 'Listing' instance"
contact_instance.user = user # assign 'user' instance
contact_instance.save() # calling 'save()' method of model
return redirect("home")
context = {
'form': form, 'user_profile': user_profile
}
return render(request, 'contact.html', context)
models.py
class User_Inquiries(models.Model):
email = models.EmailField(max_length=100, null=True)
name = models.CharField(max_length=100, null=True)
subject = models.CharField(max_length=100, null=True)
message = models.CharField(max_length=100, null=True)
user = models.ForeignKey(settings.AUTH_USER_MODEL, null=False, on_delete=models.CASCADE)
date_submitted = models.DateTimeField(auto_now_add=True, null=True)
class Meta:
verbose_name_plural = "User Inquiries"
#property
def user_message(self):
return truncatechars(self.message, 30)
What you can do is :
First, add a user field with null=True
class User_Inquiries(models.Model):
# ....
user = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, on_delete=models.CASCADE)
# ...
Second, in your view, you need to provide the user field only if the user is authenticated. Because AnonymousUser can be saved in the database.
def account_view_contact(request):
user_profile = User_Info.objects.all()
# If it's a post request
if request.method == "POST":
form = ContactUsForm(request.POST, request.FILES or None,)
if form.is_valid():
if request.user is authenticated:
# Only authenticated user can be assigned
contact_instance = form.save(commit=False)
contact_instance.user = request.user
contact_instance.save()
return redirect("home")
else:
# Save the form without user because no user is logged in
form.save()
# Handle no POST request
else:
form = ContactUsForm()
context = {
'form': form, 'user_profile': user_profile
}
return render(request, 'contact.html', context)
the User_Inquiries model user should be blank = True and null = True. In the view check if the user is logged in before setting the contact_instance.user to user.
models.py
class User_Inquiries(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, blank=True, on_delete=models.CASCADE)
views.py
def account_view_contact(request):
form = ContactUsForm(request.POST or None, request.FILES or None,)
user_profile = User_Inquiries.objects.all()
user_profile = User_Info.objects.all()
# check if the user is authenticated
if request.user.is_authenticated:
user = request.user
if request.method == "POST": # checking if request is POST or Not
# if its a post request, then its checking if the form is valid or not
if form.is_valid():
contact_instance = form.save(commit=False) # "this will return the 'Listing' instance"
contact_instance.user = user # assign 'user' instance
contact_instance.save() # calling 'save()' method of model
return redirect("home")
context = {
'form': form, 'user_profile': user_profile
}
return render(request, 'contact.html', context)
check if user is authenticated in django
set null and blank = True
I tried the above solutions and it worked. I also used CreateView to figure this out and it worked flawlessly. Code below:
class account_view_contact(CreateView):
model = User_Inquiries
form_class = ContactUsForm
template_name = "contact.html"
success_url = reverse_lazy("home")
def form_valid(self, form):
if self.request.user.is_authenticated:
self.object = form.save(commit=False)
self.object.created_by = self.request.user
self.object.save()
else:
self.object = form.save(commit=False)
self.object.save()
return super().form_valid(form)
Thanks Everyone!

Not getting fields prefilled with previous values while editing a form in django

I have a form(EditProfileForm) which I created to edit the profile details. My issue is that whenever I go to the EditProfileForm page in the browser the fields are not filled with previous values which I gave while making the profile for the first time, I have to fill the entire form however if I make some change in the value then the change is being made successfully.
my Profile model:
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
image = models.ImageField(default='profile_pic.jpg', upload_to='profile_pictures')
location = models.CharField(max_length=100, blank=True, null=True)
bio = models.CharField(max_length=500, blank=True, null=True)
def __str__(self):
return self.user.username
my EditProfileForm in forms.py:
class EditProfileForm(forms.ModelForm):
class Meta:
model = Profile
fields = ['image', 'location', 'bio']
my two views regarding profile and edit profile:
#login_required
def profile_page(request):
user = request.user
posts = Post.objects.filter(author=user)
posts_count = posts.count()
profile = Profile.objects.get(user=user)
return render(request, 'blog_app/profile.html', {'user': user, 'posts_count': posts_count, 'profile': profile})
def edit_profile(request, id):
profile = Profile.objects.get(id=id)
if request.method == 'GET':
form = EditProfileForm(request.FILES, instance=profile)
else:
form = EditProfileForm(request.POST, request.FILES, instance=profile)
if form.is_valid():
# deleting old uploaded image.
image_path = profile.image.path
if os.path.exists(image_path):
os.remove(image_path)
# the `form.save` will also update the newest image & path.
form.save()
return redirect('profile')
return render(request, 'blog_app/edit_profile.html', {'profile': profile, 'form': form})
my two urls about profile and edit profile:
path('profile', user_views.profile_page, name='profile'),
path('edit_profile/<int:id>', user_views.edit_profile, name='edit_profile')
By the way I used django signals to automatically create profile for the first time.
The way I work with ModelForm is:
form = EditProfileForm(request.POST or None, request.FILES or None, instance=profile)
I don't know what is actually the difference between these two statements:
form = EditProfileForm(request.POST or None, request.FILES or None, instance=profile)
and
form = EditProfileForm(request.FILES, instance=profile)
But, You can try with this.
You can replace the edit_profile(request, id) function with this:
def edit_profile(request, id):
profile = Profile.objects.get(id=id)
form = EditProfileForm(request.POST or None, request.FILES or None, instance=profile)
if request.method =='POST':
if form.is_valid():
# deleting old uploaded image.
image_path = profile.image.path
if os.path.exists(image_path):
os.remove(image_path)
# the `form.save` will also update the newest image & path.
form.save()
return redirect('profile')
return render(request, 'blog_app/edit_profile.html', {'profile': profile, 'form': form})

How to add username in admin page who logged in when withdrawing an amount?

I have made a form to give an option for user to withdraw money. That data is saving in admin page but the problem is I have owner variable also, which I want that as the amount data is going to be saved in admin page the owner username should also be saved in admin, which shows who is desiring this amount?
models.py
from django.contrib.auth.models import User
class WithdrawPayment(models.Model):
payment = models.CharField(max_length=100)
owner = models.ForeignKey(User, on_delete=models.CASCADE)
class Meta:
verbose_name_plural = 'Withdraw Payment'
views.py
#login_required
def withdraw(request):
if request.method == 'POST':
form = WithdrawBalance(request.POST, request.FILES)
if form.is_valid():
form.save()
messages.success(request, f'Your request has been submitted.')
return redirect('index')
else:
form = WithdrawBalance()
context = {'form': form}
return render(request, 'nextone/withdraw.html', context)
forms.py
class WithdrawBalance(forms.ModelForm):
class Meta:
model = WithdrawPayment
fields = ['payment']
Something like this:
#login_required
def withdraw(request):
form_class = WithdrawBalanceForm
if request.method == 'POST':
form = form_class(request.POST)
obj = form.save(commit=False)
obj.owner = request.user
obj.save()
messages.success(request, f'Your request has been submitted.')
return redirect('index')
else:
form = form_class()
context = {'form': form}
return render(request, 'nextone/withdraw.html', context)
class WithdrawBalanceForm(forms.ModelForm):
class Meta:
model = WithdrawPayment
fields = ['payment']

Categories

Resources