I have a Django form that allows a user to save their UserProfile details, but it only allows this to occur once. Given that additional saves ask to create a new entry, but i have a one-to-one relation between the user field and user UserProfile field.
When a user is created a UserProfile entry is not created. Rather they cannot access their account until these details are filled out.
I want to pre-populate the form with existing data when a student goes to access the form a second time.
def student_details(request):
#this is a form
if request.user.is_authenticated():
if request.method == 'POST':
form = DetailsForm(request.user, request.POST, request.FILES)
if form.is_valid():
note = form.save(commit=False)
note.user = request.user
note.completed_form = True
note.save()
return HttpResponseRedirect('/student-portal/')
else:
if request.user.get_profile():
pass
form = DetailsForm(request.user)
else:
form = DetailsForm(request.user)
return render_to_response("student-details.html", {'form': form}, context_instance=RequestContext(request))
return HttpResponseRedirect('/')
Sorry guys just found out how to do this:
def student_details(request):
#this is a form
if request.user.is_authenticated():
if request.method == 'POST':
form = DetailsForm(request.user, request.POST, request.FILES)
if form.is_valid():
note = form.save(commit=False)
user_profile = UserProfile.objects.get(user=request.user)
if user_profile:
note.id = user_profile.id
note.user = request.user
note.completed_form = True
note.save()
return HttpResponseRedirect('/student-portal/')
else:
try:
user_profile = UserProfile.objects.get(user=request.user)
form = DetailsForm(request.user, instance=user_profile)
except:
form = DetailsForm(request.user)
return render_to_response("student-details.html", {'form': form}, context_instance=RequestContext(request))
return HttpResponseRedirect('/')
The idea here is to query to see if a user_profile linked to that user already exists and then specify the ID for that entry.
Related
def create_new(request):
if request.method == 'POST':
form = ArticleForm(request.POST)
form.id_author = request.user.id
if form.is_valid():
form.save()
return redirect('home')
return render(request, 'main/create_new.html')
def create_new(request):
if request.method == 'POST':
form = ArticleForm(request.POST)
if form.is_valid():
article = form.save(commit=False)
article.author = request.user
article.save()
return redirect('home')
return render(request, 'main/create_new.html')
Is it possible to change the 2nd code into the first code??
it shows some kind of error
No, at first you always need to check whether the form is valid or not, then after you can save the form with commit=False which creates a temporary instance, then you should assign any value in that instance.
The second approach is correct.
I always get this Error
DoesNotExist at /file/new/1
StaffUser matching query does not exist.
My models.py
class StaffUser(User):
department = models.ForeignKey(Dept, on_delete=models.RESTRICT)
My Views.py
def FileUploadForm(request, pk):
if request.method == 'POST':
form = UploadFileForm(request.POST, request.FILES)
folder = Folder.objects.get(id=pk)
if form.is_valid():
form.save(commit=False)
u = StaffUser.objects.get(username=request.user)
form.instance.fileuser = u
form.instance.folder = folder
form.instance.department = u.department
form.save()
messages.success(request, f'File Successfully uploaded to {folder}!')
return redirect('home')
else:
form = UploadFileForm()
return render(request, "pages/fileup_form.html", {'form': form, 'pk':pk})
I want to get the department of the user and add to the database
I have 2 user types, teacher and student. I have built the view to be able to edit a student profile. But I also needed a different one for teacher. I didn't want 2 views, because that would be pointless. Now, for teacher it works as intended, but for some reason for student, the same form as for teacher is displayed... a student has different attributes so it has a different form I need to show.
#login_required
def profile_edit(request):
user = request.user
student = request.user.student
teacher = request.user.teacher
if user == teacher.user:
if request.method != 'POST':
form = TeacherEditForm(instance=teacher)
else:
form = TeacherEditForm(request.POST, instance=teacher)
if form.is_valid():
user.email = form.cleaned_data['email']
user.save()
form.save()
return redirect('index')
elif user == student.user:
if request.method != 'POST':
form = StudentEditForm(instance=student)
else:
form = StudentEditForm(request.POST, instance=student)
if form.is_valid():
user.email = form.cleaned_data['email']
user.save()
form.save()
return redirect('index')
context = {
"form": form,
}
return render(request, "registration/profile_edit.html", context)
I think there is something wrong with the way I pass data to student and teacher and the view can't differentiate between user types.
Something like this but remove
User.student = property(lambda p: Student.objects.get_or_create(user=p)[0])
User.teacher = property(lambda p: Teacher.objects.get_or_create(user=p)[0])
#login_required
def profile_edit(request):
user = request.user
try:
student = Student.objects.get(user=user)
s=True
except: teacher = Teacher.objects.get(user=user)
if not s:
if request.method != 'POST':
form = TeacherEditForm(instance=teacher)
else:
form = TeacherEditForm(request.POST, instance=teacher)
if form.is_valid():
user.email = form.cleaned_data['email']
user.save()
form.save()
return redirect('index')
elif s:
if request.method != 'POST':
form = StudentEditForm(instance=student)
else:
form = StudentEditForm(request.POST, instance=student)
if form.is_valid():
user.email = form.cleaned_data['email']
user.save()
form.save()
return redirect('index')
context = {
"form": form,
}
return render(request, "registration/profile_edit.html", context)
I want to redirtect page, after saving modelform. when i pushed save button, page redirecte, but no any things saved.
def channelAdd(request):
if request.method == 'POST':
form = ChannelForm(request.POST)
if form.is_valid():
channelid = form.cleaned_data['channelid']
form.save()
return HttpResponseRedirect(reverse('updateChannelInfo', args=[channelid]))
else:
form = ChannelForm()
return render(request, 'web/channelAdd.html', {'form':form})
This will get you closer to the solution. I'm not positive if you have 'updateChannelInfo' as the name in urls.py (so please double-check that). I think the complexity here is getting the correct channelId to be sent
def channelAdd(request):
if request.method == 'POST':
form = ChannelForm(request.POST)
if form.is_valid():
channelid = form.cleaned_data['channelid']
form.save()
return HttpResponseRedirect(reverse('updateChannelInfo', args = [self.object.id])))
else:
form = ChannelForm()
return render(request, 'web/channelAdd.html', {'form':form})
If you are willing to share your urls.py and forms.py files, this would help with getting the correct names into arguments
Another way I have had success with the dynamic direct after form submission is to use
def add_channel (request):
if request.method == 'POST':
form = ChannelForm(request.POST)
if form.is_valid():
channel.save()
return HttpResponseRedirect(reverse('channel_detail', args=[channel.id]))
else:
form = ChannelForm()
return render(request, 'channel_example.html', {'form': form})
Edit your view like this,
if form.is_valid():
form.save()
return redirect('updateChannelInfo', channelId=self.object.id)
I have a page for updating a user profile in my django project. The view code looks like this:
#login_required
def updateProfile(request, user_id):
if request.method == 'POST':
form = UserProfileForm(request.POST)
if form.is_valid():
form.user_id = user_id
form.save(commit=True)
return index(request)
else:
profile, created = UserProfile.objects.get_or_create(user_id = self.user_id) # don't know if this will actually work.
profile_form = UserProfileForm(profile)
context = {
'user' : request.user,
'form' : profile_form
}
return render(request, 'myapp/profile.html', context)
My form looks like this:
class UserProfileForm(forms.ModelForm):
class Meta:
model = UserProfile
fields = ['age', 'skill_level']
My user profile looks like this:
class UserProfile(models.Model):
user = models.ForeignKey(User, unique=True)
age = models.IntegerField(default=18)
skill_level = models.ForeignKey(SkillLevel)
When this gets posted to, we receive what appears to be a valid user_id along with a valid form. In the UserProfileForm form we do not include user_id so that when it renders the user cannot decide to swap that out. Instead, the user_id gets posted back as a separate parameter (as I type this out, I realize it's kind of weird..). I want to save the UserProfile encapsulated by UserProfileForm to the database on post, so I give it a user_id and try to call .save(commit=True) on it, which returns "Column 'user_id' cannot be null".
My question is simple, how can I get that underlying UserProfile object saved from the form data with the information at hand?
Standard Django form handling idiom in case like that is
#login_required
def updateProfile(request, user_id):
if request.method == 'POST':
form = UserProfileForm(request.POST)
if form.is_valid():
obj = form.save(commit=False) # Get just object, but don't save yet
obj.user = request.user # set user (or user_id)
obj.save() # Save object
return index(request)
else:
profile, created = UserProfile.objects.get_or_create(user_id = self.user_id) # don't know if this will actually work.
profile_form = UserProfileForm(profile)
context = {
'user' : request.user,
'form' : profile_form
}
return render(request, 'myapp/profile.html', context)
Note that form data is not in fields, so form.my_field = 123 won't work - form data is parsed to form.cleaned_data dictionary where form.save() reads it.
use the request.user for userProfile user, do this way
#login_required
def updateProfile(request, user_id):
if request.method == 'POST':
form = UserProfileForm(request.POST)
form.user = request.user
if form.is_valid():
form.save(commit=True)
return index(request)
else:
profile, created = UserProfile.objects.get_or_create(user = request.user) # don't know if this will actually work.
profile_form = UserProfileForm(instance=profile)
context = {
'user' : request.user,
'form' : profile_form
}
return render(request, 'myapp/profile.html', context)