Django - Unable to find object using pk (Matching query DoesNotExist) - python

Whenever I try to create a "Tour" for a "User" I get this error:
"DoesNotExist at /add-tour/FAjK5CryF8/ - User matching query does not exist."
Specifically the problems seems to come from this line of code:
user = User.objects.get(pk=pk)
models.py
class Tour(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
tour_date = models.DateField(default=date.today)
tour_fans = models.ForeignKey(FanAccount, on_delete=models.PROTECT)
def __str__(self):
return f"{self.user} del {self.tour_date}"
views.py
def tour_new(request, pk):
user = User.objects.get(pk=pk)
if request.method == "POST":
form = TourForm(request.POST)
if form.is_valid():
instance = form.save(commit=False)
instance.tour_fans = request.user
form.instance.user = user
instance.save()
form.save()
return render(request, "tour.html", {"form": TourForm(), "success": True})
else:
form = TourForm()
return render(request, "tour.html", {"form": form})
For "User" I'm using a custom Primary Key (ShortUUID).
I'm new to Python and Django so it may be something easily solvable, but after hours of attempts I seem unable to solve it.

You need to make sure your user instance does exist, so you should instead of user = User.objects.get(pk=pk)call user = get_object_or_404(User, pk=pk), then you need to pass user as an instance:
if request.method == "POST":
form = TourForm(request.POST, instance=user)

Related

I had 'NoneType' object has no attribute 'groups' in django

I'm new in django,I just have the error, AttributeError at /registro/ 'NoneType' object has no attribute 'groups', but my form is saving all the data
views.py
def register(request):
if request.method == 'POST':
form = CreateUserForm(request.POST)
if form.is_valid():
ui = User()
ui.username = request.POST.get('username')
ui.password = request.POST.get('password')
ui.first_name = request.POST.get('first_name')
ui.last_name = request.POST.get('last_name')
ui.email = request.POST.get('email')
# user = User.objects.create_user(username=username,first_name=first_name,last_name=last_name,email=email,password=password)
user = ui.save()
obj = User.objects.latest('id')
cli = Client_profile_master()
cli.first_name = request.POST.get('first_name')
cli.last_name = request.POST.get('last_name')
cli.email = request.POST.get('email')
cli.mobile_no = request.POST.get('mobile')
cli.address_1 = request.POST.get('address1')
cli.address_2 = request.POST.get('address2')
cli.image=request.FILES.get('image')
cli.user=obj
# emp.save()
# client = Client_profile_master.objects.create(first_name=first_name,last_name=last_name,email=email,mobile=mobile,address1=address1,address2=address2,image=image,user=obj)
cli.save()
username = form.cleaned_data.get('username')
group = Group.objects.get(name='Client')
user.groups.add(group)
messages.success(
request, f'Account created successfully for {username} !!!')
return redirect('login')
else:
return redirect('/')
else:
form = CreateUserForm()
return render(request, 'sites/register.html', {'form': form})
The error is occuring for this line: user = ui.save(), Model's save method does not return anything(or returns None), hence value of user is None. Easy fix would be to use ui.groups.add(group).
But you can improve your implementation a lot by using the forms, which you are already using as well as by adding a new one. For example:
# form
class CliForm(forms.ModelForm):
class Meta:
model = ClientProfileMaster # Using camelcase when declairing class name
exclude = ["user",]
# view
form = CreateUserForm(request.POST)
cli_form = CliForm(request.POST, request.FILES)
if form.is_valid() and cli_form.is_valid():
user = form.save()
cli = cli_form.save(commit=False)
cli.user = user
cli.save()
For more information, please the django modelform's documentation.

Django model form, adding a user id when creating new note

I'm pretty new to Django, I've been stuck on this view for a little while. My goal with this form is to be able to create a small note on a "Property" about maintenance or other information. The note would log the time, date, note and the user that recorded the note. Any help would be appreciated.
View:
#login_required(login_url="login")
def createNote(request, pk):
PropertyNoteFormSet = inlineformset_factory(
Property, PropertyNote, fields=('note', 'user',))
property_note = Property.objects.get(id=pk)
form = PropertyNoteFormSet(instance=property_note)
# form = OrderForm(initial={'customer': customer})
if request.method == "POST":
print(request.POST)
form = PropertyNoteFormSet(
request.POST, instance=property_note)
if form.is_valid():
form.save()
return redirect("/")
context = {"form": form}
return render(request, "dashboard/create_note.html", context)
Here is the ModelForm:
class PropertyNoteForm(ModelForm):
class Meta:
model = PropertyNote
fields = ['note']
exclude = ['user']
Here is the Model:
class PropertyNote(models.Model):
airbnb_name = models.ForeignKey(Property, blank=True,
null=True,on_delete=models.CASCADE)
note = models.TextField(blank=True, null=True)
user = models.ForeignKey(User, on_delete=models.CASCADE)
created_on = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.note
The form comes out with around 4 boxes to fill in. Currently it works, but you have to actually select the user that is posting the note, I would like this part to be handled automatically and use the current logged in user. I think I still have a whole lot of holes in my knowledge around this stuff, I just can't seem to work it out.
Thanks in advance.
Edit:
I've tried this:
def createNote(request, pk):
PropertyNoteFormSet = inlineformset_factory(
Property, PropertyNote, fields=('note',), extra=1)
property_note = Property.objects.get(id=pk)
form = PropertyNoteFormSet(
queryset=PropertyNote.objects.none(), instance=property_note)
# form = OrderForm(initial={'customer': customer})
if request.method == "POST":
print(request.POST)
form = PropertyNoteFormSet(
request.POST, instance=property_note)
if form.is_valid():
instance = form.save(commit=False)
instance.user = request.user
print(instance.user)
instance.save()
return redirect("/")
context = {
"form": form,
'pk': pk,
}
return render(request, "dashboard/create_note.html", context)
But I get this:
AttributeError at /create_note/75/
'list' object has no attribute 'user'
Request Method: POST
Request URL: http://127.0.0.1:8000/create_note/75/
Django Version: 3.0.4
Exception Type: AttributeError
Exception Value:
'list' object has no attribute 'user'
you can use request.user.id to get the logged user id in your view.
See Documentation in Django
#login_required(login_url="login")
def createNote(request, pk, **kwargs):
note_form = PropertyNoteForm()
if request.method == "POST":
note_form = PropertyNoteForm(request.POST)
if note_form.is_valid():
add_note = note_form.save(commit=False)
add_note.user = request.user
add_note.airbnb_name =
Property.objects.get(id=pk)
add_note.save()
return redirect('/property/' + pk + '/')
context = {
"form": note_form,
'pk': pk,
}
return render(request, "dashboard/create_note.html", context)
I solved it with the above code. Using instance was the incorrect thing to do here. I didn't need to create an instance and I didn't need the inline form. I simply needed a new form:
note_form = PropertyNoteForm()
The user input information, I need to send that information to check if it's valid:
if request.method == "POST":
note_form = PropertyNoteForm(request.POST)
if note_form.is_valid():
Then I needed to populate the form with information that was not already in the form from the user:
add_note = note_form.save(commit=False)
add_note.user = request.user
add_note.airbnb_name = Property.objects.get(id=pk)
add_note.save()
return redirect('/property/' + pk + '/')

Remove user in Django

I would like to remove user.
I know that probably I can use some library like allauth but I want to do this on my view.
I didn't find any tutorial for that so I am trying to do this learn-by-mistakes way.
Ok. so in urls I have:
urlpatterns = [
('^remove$', views.remove_user, name="remove"),
]
forms:
class RemoveUser(forms.ModelForm):
class Meta:
model = User
fields = ('username',)
views:
#login_required(login_url='http://127.0.0.1:8000/')
def remove_user(request):
if request.method == 'POST':
form = RemoveUser(request.POST)
username = request.POST.get('username')
if form.is_valid():
rem = User.objects.get(username=username)
rem.delete()
return redirect('main')
else:
form = RemoveUser()
context = {'form': form}
return render(request, 'remove_user.html', context)
I can access website and type text in textfield. When I type random username I get error "user does not exist" so everything ok, but when I type correct username I get message: "A user with that username already exists" and this user is not removed.
Please, can you help me with that?
Change your form to a normal form-
class RemoveUser(forms.Form):
username = forms.CharField()
The view will be as follows -
#login_required(login_url='http://127.0.0.1:8000/')
def remove_user(request):
if request.method == 'POST':
form = RemoveUser(request.POST)
if form.is_valid():
rem = User.objects.get(username=form.cleaned_data['username'])
if rem is not None:
rem.delete()
return redirect('main')
else:
## Send some error messgae
else:
form = RemoveUser()
context = {'form': form}
return render(request, 'remove_user.html', context)
EDIT-- Another way to approach the same problem is to deactivate the user
if form.is_valid():
rem = User.objects.get(username=form.cleaned_data['username'])
if rem is not None:
rem.is_active = False
rem.save()

How to update a form attribute from view code in django

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)

Django UserProfile Forms

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.

Categories