I need to assign posts to user in Django. I created
user = models.ForeignKey('authentication.CustomUser', on_delete=models.CASCADE)
and then if I display this model in my form.html I have to choice one of all users, if I don't display user in my form.html the form's isn't save my views file :
def formularz(request):
form = DodajForm(request.POST)
if form.is_valid():
ogloszenie = form.save(commit=False)
ogloszenie.user = request.user
ogloszenie.save()
return redirect('atrakcje:after')
else:
ogloszenie = DodajForm()
context = {
'form': form,}
return render(request, 'formularz.html', context)
Can i please know how to resolve it?
Rewrite the form to exclude the user field:
class DodajForm(forms.ModelForm):
class Meta:
model = Dodaj
exclude = ['user']
In the view, you better alter the instance, and let the form do the save logic, since a ModelForm can also save many-to-many fields:
def formularz(request):
if request.method == 'POST':
form = DodajForm(request.POST, request.FILES)
if form.is_valid():
form.instance.user = request.user
form.save()
return redirect('atrakcje:after')
else:
ogloszenie = DodajForm()
context = {'form': form}
return render(request, 'formularz.html', context)
Related
I have a simple model which has four different fileFields for uploading different files and images.
this is my models:
class DocumentInfo(models.Model):
id = models.AutoField(primary_key=True)
certificate = models.FileField(upload_to="documents", null=True)
id_card = models.FileField(upload_to="documents", null=True)
service_certificate = models.FileField(upload_to="documents", null=True)
educational_certificate = models.FileField(upload_to="documents", null=True)
users need to simply upload some images in four individual fields so, I created a simple form and passed it to views like this:
class DocumentForm(forms.ModelForm):
class Meta:
model = DocumentInfo
fields = ['certificate','id_card','service_certificate','educational_certificate']
views.py:
def document_info(request):
if request.method == 'POST':
form = DocumentForm(request.POST, request.FILES)
if form.is_valid():
form.instance.user = request.user
form.save()
return redirect('document')
if 'delete' in request.GET:
return delete_item(DocumentInfo, request.GET['id'])
else:
form = DocumentForm()
documents = DocumentInfo.objects.filter(user=request.user)
context = {
'form': form,
'documents': documents,
}
return render(request, 'reg/documents.html', context)
it works just fine at first but I cant reupload anything! the uploaded image neither gets saved the second time around nor deleted. what am I doing wrong?
try this.
views.py
def document_info(request):
documents = DocumentInfo.objects.filter(user=request.user).order_by('-pk')
if request.method == 'POST':
if documents:
form = DocumentForm(request.POST, request.FILES,instance=documents[0])
else:
form = DocumentForm(request.POST, request.FILES)
if form.is_valid():
if not documents:
form.instance.user = request.user
form.save()
return redirect('document')
else:
if documents:#if the user already has a document.
form = DocumentForm(instance=documents[0])
else:
form = DocumentForm()
context = {
'form': form,
'documents': documents,
}
return render(request, 'reg/documents.html', context)
My UserImg Model has a user field that has editable=False.
I want this field to be automatically filled in with the user name when the user is saved from web page.
model.py
def upload_myimg_path(instance, filename):
return 'documents/{0}/{1}'.format(instance.created_by.username, filename)
class UserImg(models.Model):
user = models.ForeignKey(User, verbose_name=_('Created by'), on_delete=models.CASCADE, editable=False, null=True, blank=True)
name = models.CharField(max_length=100, default='')
image = models.ImageField(upload_to=upload_myimg_path, verbose_name=_('File'))
def __str__(self):
return str(self.user)
forms.py
class UserImgForm(forms.ModelForm):
class Meta:
model = UserImg
fields = '__all__'
views.py
def createuserimg(request):
if request.method == 'POST':
form = UserImgForm(request.POST or None)
if form.is_valid():
form.save()
return redirect('/accounts/users')
else:
return redirect('/accounts/')
else:
form = UserImgForm
return render(request, 'accounts/user_form.html', {'form': form})
Update your view function to include current logged in user and make use of #login_required decorator to ensure that only logged in users can access this view :
from django.contrib.auth.decorators import login_required
#login_required
def createuserimg(request):
if request.method == 'POST':
form = UserImgForm(request.POST, request.FILES)
if form.is_valid():
obj = form.save(commit=False) # <-- commit=False does not save to database
obj.user = request.user # <-- this allows you to specify the user for your post
obj.save()
return redirect('/accounts/users')
# if the form did not validated, stay on the same page to display errors to your user
else:
form = UserImgForm()
return render(request, 'accounts/user_form.html', {'form': form})
correct answer commit=False allows you to modify the resulting object before it is actually saved to the database. It`s works for me.
Thank you very much for your help
from django.contrib.auth.decorators import login_required
#login_required
def createuserimg(request):
if request.method == 'POST':
form = UserImgForm(request.POST, request.FILES)
if form.is_valid():
link = form.save(commit=False)
link.user = request.user
link.save()
return redirect('/accounts/users')
# if the form did not validated, stay on the same page to display errors to your user
else:
form = UserImgForm()
return render(request, 'accounts/user_form.html', {'form': form})
This is my code for my view:
def edit(request):
if request.method == 'POST':
form = EditProfileForm(request.POST, instance=request.user)
else:
if form.is_valid():
user = form.save()
form = EditProfileForm(instance=request.user)
args = {'form': form}
return render(request, 'social/edit.html', args)
And here is the code for the form:
class EditProfileForm(UserChangeForm):
edit ='social/edit.html'
class Meta:
model = UserProfile
fields = ('description', 'image')
Here is the model:
class UserProfile(models.Model):
description = models.CharField(max_length=300, default=' ', blank=True)
image = models.ImageField(upload_to='profile_image', blank=True)
if you need any more information to help I would be more than gladly to give it to you
The problem is with the view function.
Every View must return some sort of response (HTTP Response in General)
you have an if else statement in your view if its a post it will just execute
form = EditProfileForm(request.POST, instance=request.user)
and then it doesn't return anything.
I think you have to do is,
For GET Request (when you visit the url, it has to render the form)
if request.method == 'GET':
form = EditProfileForm(instance=request.user)
args = {'form': form}
return render(request, 'social/edit.html', args)
For POST request (when you send POST to this view or different one)
if request.method == 'POST':
form = EditProfileForm(request.POST, instance=request.user)
if form.is_valid():
user = form.save()
# use render/redirect as needed. make sure it returns an HTTP Response
# note that render method also return HTTP Response
return HttpResponse('Done')
Make sure Form class is simply this
class EditProfileForm(UserChangeForm):
class Meta:
model = UserProfile
fields = ('description', 'image')
So i have a model that i'm trying to save using a form which submits successfully, but in the Admin the object value None. I know the problem is in the views but i can't figure it out. Here's my code:
Views.py
def profilecreate(request):
if request.method == 'GET':
form = ProfileForm()
else:
form = ProfileForm(request.POST)
if form.is_valid():
description = form.cleaned_data['description']
caption= form.cleaned_data['caption']
photo = form.cleaned_data['photo']
profile = Profile.objects.create(description=description, caption=caption, photo=photo)
return HttpResponseRedirect(reverse('profile-id', kwargs={'profile_id': profile.id}))
return render(request, 'profile_form.html', {'form': form})
Someone please assist
Second view attempt
def profilecreate(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 = ProfileForm(request.POST)
# check whether it's valid:
if form.is_valid():
photo = form.cleaned_data['photo']
description = form.cleaned_data['description']
caption = form.cleaned_data['caption']
form.save(commit=True)
return HttpResponseRedirect('/')
# if a GET (or any other method) we'll create a blank form
else:
form = ProfileForm()
return render(request, 'profile_form.html', {'form': form})
Consider this simple user profile:
from django.contrib.auth.models import User
class UserProfile(models.Model):
user = models.OneToOneField(User)
onboarding_step = models.SmallIntegerField(default='1')
What is the simplest method it increment the onboarding_step within UserProfile each time a separate form from a different model is submitted? For example:
Here's the ModelForm (from a separate model, Site) I am submitting:
class OnBoardingProgressForm(forms.ModelForm):
class Meta:
model = Site
fields = ( 'abc', 'xyz', )
And here is the view.py for the form:
if request.method == "POST":
form = OnBoardingProgressForm( request.POST )
if form.is_valid():
....
THIS CODE DOES NOT WORK BUT IS MY BEST GUESS:
last = request.user.profile
last.onboarding_step = 2
....
obj = form.save(commit=False)
obj.user = current_user
obj.save()
return render(request, "nextpage.html", {'form': form })
How can I increment the user.onboarding_step by 1?
if request.method == "POST":
form = OnBoardingProgress( request.POST )
if form.is_valid():
....
// Can I increment the code here? //
....
obj = form.save(commit=False)
obj.user = current_user
obj.save()
user_obj = UserProfile.objects.get(user=request.user)
user_obj.onboarding_step = user_obj.onboarding_step + 1
user_obj.save()
return render(request, "nextpage.html", {'form': form })
or you can make autoincrement field also.
Get the UserProfile object for the current user and then increment the value of the attribute of onboarding_step.
Try this:
if request.method == "POST":
form = OnBoardingProgress(request.POST)
current_user = request.user
if form.is_valid():
user_profile = UserProfile.objects.filter(user=current_user)[0] # get the user profile object for the current user
user_profile.onboarding_step += 1 # increment the value
user_profile.save() # save the object
obj = form.save(commit=False)
obj.user = current_user
obj.save()
return render(request, "nextpage.html", {'form': form })