Get Django Auth "User" id upon Form Submission - python

I currently have a model form that submits an entered domain to the db.
The problem I'm encountering is, I need to save the currently logged in user's ID (PK from the django.auth table) when a domain is submitted to satisfy a PK-FK relationship on the db end.
I currently have:
class SubmitDomain(ModelForm):
domainNm = forms.CharField(initial=u'Enter your domain', label='')
FKtoClient = User.<something>
class Meta:
model = Tld #Create form based off Model for Tld
fields = ['domainNm']
def clean_domainNm(self):
cleanedDomainName = self.cleaned_data.get('domainNm')
if Tld.objects.filter(domainNm=cleanedDomainName).exists():
errorMsg = u"Sorry that domain is not available."
raise ValidationError(errorMsg)
else:
return cleanedDomainName
and views.py
def AccountHome(request):
if request.user.is_anonymous():
return HttpResponseRedirect('/Login/')
form = SubmitDomain(request.POST or None) # A form bound to the POST data
if request.method == 'POST': # If the form has been submitted...
if form.is_valid(): # If form input passes initial validation...
domainNmCleaned = form.cleaned_data['domainNm'] ## clean data in dictionary
clientFKId = request.user.id
form.save() #save cleaned data to the db from dictionary`
try:
return HttpResponseRedirect('/Processscan/?domainNm=' + domainNmCleaned)
except:
raise ValidationError(('Invalid request'), code='300') ## [ TODO ]: add a custom error page here.
else:
form = SubmitDomain()
tld_set = request.user.tld_set.all()
return render(request, 'VA/account/accounthome.html', {
'tld_set':tld_set, 'form' : form
})
The problem is it gives me an error of: (1048, "Column 'FKtoClient_id' cannot be null"), very odd thing happening, for the column FKtoClient, its trying to submit: 7L instead of 7(the PK of this user's record). Any ideas?
If someone can please help, I would really appreciate it

Firstly, remove FKtoClient from your form. You need to set the user in your view where you can yes the request object. It's not possible to set an attribute on the form that automatically sets the current user.
When instantiating your form, you can pass a tld instance which already has the user set.
def AccountHome(request):
# I recommend using the login required decorator instead but this is ok
if request.user.is_anonymous():
return HttpResponseRedirect('/Login/')
# create a tld instance for the form, with the user set
tld = Tld(FKtoClient=request.user)
form = SubmitDomain(data=request.POST or None, instance=tld) # A form bound to the POST data, using the tld instance
if request.method == 'POST': # If the form has been submitted...
if form.is_valid(): # If form input passes initial validation...
domainNm = form.cleaned_data['domainNm']
form.save() #save cleaned data to the db from dictionary
# don't use a try..except block here, it shouldn't raise an exception
return HttpResponseRedirect('/Processscan/?domainNm=%s' % domainNm)
# No need to create another form here, because you are using the request.POST or None trick
# else:
# form = SubmitDomain()
tld_set = request.user.tld_set.all()
return render(request, 'VA/account/accounthome.html', {
'tld_set':tld_set, 'form' : form
})
This has an advantage over #dm03514's answer, which is that you can access the user within form methods as self.instance.user if required.

If you want to Require that a user be logged in to submit a form, you could do something like:
#login_required # if a user iS REQUIRED to be logged in to save a form
def your_view(request):
form = SubmitDomain(request.POST)
if form.is_valid():
new_submit = form.save(commit=False)
new_submit.your_user_field = request.user
new_submit.save()

You can get the logged in user from the request object:
current_user = request.user

Related

NOT NULL constraint failed: mainsite_customer.user_id

I just wanna get profile with full form or empty form.
def local_cabinet(request):
user_id = request.user.id
caruser = Checkout.objects.filter(user=request.user)
# form = CheckoutForms()
orders = request.user.orderitem_set.all()
total_orders = orders.count()
ready_order = request.user.order_set.all()
customer = Customer.objects.filter(user=request.user)
customer_form = CustomerForm()
Maybe here's problem I don't know:
if request.method == 'POST':
if customer.exists():
form = CustomerForm(request.POST, request.FILES, instance=customer)
else:
form = CustomerForm(request.POST)
if form.is_valid():
form.save()
context = {
'caruser': caruser,
'orders': orders,
'total_orders': total_orders,
'ready_order': ready_order,
'cat_selected': 0,
'customer_form': customer_form,
'customer': customer,
}
return render(request, 'localcabinet.html', context=context)
I don't know why I get this, maybe because I'm not right at saving the form.
You are missing User instance in form, that you probably need to pass it after form creation and before saving it.
You didn't provide model nor forms, but I guess it will look like this:
if request.method == 'POST':
...
else:
form = CustomerForm(request.POST)
form.user = request.user
if form.is_valid():
form.save()
...
Another thing is that you assign queryset instead of single object with filter method:
customer = Customer.objects.filter(user=request.user) # gives queryset with probably one object
customer = Customer.objects.get(user=request.user) # gives an object - but gives Error if there is None or more than one
Probably the best approach to get single object is with try and except:
try:
customer = Customer.objects.get(user=request.user)
except Customer.DoesNotExists:
customer = None
then later instead of if customer.exists() you can use simple if customer.

Why does my Submit button renders a page that is blank when it is supposed to contain the data that was just updated?

I'm trying to update the values of my database using a HTML Form.
When I Click Edit it brings me to the edit the values above.
However as I am clicking the submit button, it returns me a database but with no other values.
Is there anyone that can help me understand what I did wrong and point me to the right documentation (if any)
editclaims.html:
<div class="arrange2">
<h1>Edit Claim Form - #{{claims.id}} </h1>
</div>
<form method="POST" action="/update/{{claims.id}}">
{% csrf_token %}
views.py:
def editclaims(request,id):
context = initialize_context(request)
user = context['user']
claims = SaveClaimForm.objects.get(id=id)
if request.method == 'POST':
name = request.POST['name']
email = request.POST['email']
claim = request.POST['claim']
claimtype = request.POST.get('claimtype')
description = request.POST['description']
receipt = request.FILES['receipt']
cheque = request.POST.get('Cheque')
form = SaveClaimForm(name=name, email=email, claim=claim, claimtype=claimtype, description=description, receipt=receipt, cheque=cheque)
form.save()
return render(request, "Login/editclaims.html", {'claims':claims, 'user':user})
urls.py:
urlpatterns = [
path('existingclaims/', views.viewclaims, name='existingclaims'),
path('editclaims/<int:id>', views.editclaims, name='editclaims'),
path('update/<int:id>', views.updateclaims, name='updateclaims'),
]
It may not resolve all your problems but it will be more readable as answer.
When you get data from HTML then you create new object SaveClaimForm and it will have new ID and you will have the same object in two rows.
You have to get original Claim from database and update values in this object and save it - and then it will save it with original ID and you will have only one `object in database
def editclaims(request,id):
context = initialize_context(request)
user = context['user']
# get original object
claims = SaveClaimForm.objects.get(id=id)
if request.method == 'POST':
# update original object
claims.name = request.POST['name']
claims.email = request.POST['email']
claims.claim = request.POST['claim']
claims.claimtype = request.POST.get('claimtype')
claims.description = request.POST['description']
claims.receipt = request.FILES['receipt']
claims.cheque = request.POST.get('Cheque')
# save it with original `ID`
claims.save()
return render(request, "Login/editclaims.html", {'claims':claims, 'user':user})
BTW:
Django has special class ModelForm to create forms in HTML. It may also have methods to check if data in HTML are correct - ie. if fields are not empty, if email is correctly constructed (name#domain.com), if phone has only numbers, etc. So using ModelForm can be more useful then writing all manually in code.

form initials do not show

i am trying to set the form initials for the sender field as the logged in user, and it does not show. i removed the if request method statement and adjusted the indentaion and the initials showed. I am stuck, i believe the form is supposed to have that request method statement. i've gone through the documentation and it says the post method binds the data and submits, but there isn't any data when the page is refreshed or newly loaded. what could be wrong?
views.py
def transfer(request):
profile = Profile.objects.get(user=request.user)
if request.method == "POST":
form = TransferForm(request.POST,initial={"sender": profile})
if form.is_valid():
print(form)
form.save()
sender = models.sendcoins.objects.get(sender=request.user.profile)
profile2 = Profile.objects.get(username=receiver)
user_wallet = wallet.objects.get(owner=profile)
print(receiver)
temp = sender # NOTE: Delete this instance once money transfer is done
receiver = models.wallet.objects.get(owner=profile2) # FIELD 1
transfer_amount = sender.amount # FIELD 2
sender = models.wallet.objects.get(owner=profile) # FIELD 3
# Now transfer the money!
sender.balance = sender.balance - transfer_amount
receiver.balance = receiver.balance + transfer_amount
# Save the changes before redirecting
sender.save()
receiver.save()
temp.delete() # NOTE: Now deleting the instance for future money transactions
else:
return(HttpResponse("form is not valid"))
else:
form = TransferForm()
return render(request, "sendcoins.html", {"form": form})

Passing Form Data to View

I have the following view:
views.py
def PackingListView(request):
if request.method == "POST":
form = PackingListForm(request.POST)
if form.is_valid():
if 'preview' in request.POST:
request.session['data'] = form.cleaned_data
return redirect('myview')
....
I would like to take the data in form and pass it to this next view, and set the data variable equal to it. This was previously working, but once I added a foreign key into this form, the session no longer works as it is not serializable. What approach is the safest for me to take here?
views.py
class myview(View):
def get(self, request, *args, **kwargs):
data = request.session.pop('data', {})#this won't work now
pdf = render_to_pdf('packlist_preview.html', data)
return HttpResponse(pdf, content_type='application/pdf')
Also in case it is needed - here is the URL for myview
url(r'^myview/', views.myview.as_view(), name='myview'),
You should be able to serialize the data if you replace the model instance with its id.
data = form.cleaned_data
# remove object from data dict
related_object = data.pop('related_object')
# add in a reference
data['related_object_id'] = related_object.pk
# now you should be able to serialize object
request.session['data'] = data
Then in the next view, you can fetch the object from the database using its id
data = request.session.pop('data', {})
related_object_id = data.pop('related_object_id', None)
if related_object_id:
try:
data['related_object'] = RelatedObject.objects.get(pk=related_object_id)
except RelatedObject.DoesNotExist:
pass

Getting error in refering user object django

def itemconfirmation(request, pk):
item = Food_item.objects.get(id=pk)
userobj = request.user
user = UserProfile.objects.get(user=userobj)
if request.method == 'POST':
count_form = CountForm(data=request.POST)
if count_form.is_valid():
countform = count_form.save(commit=False)
countform.useradno = user.adno
countform.itemid = item.id
countform.save()
c = RequestContext(request, {
'item': item, 'count_form': count_form
})
return render_to_response('itemconfirmation.html', context_instance=c)
I have a view defined like this. I'm getting error in making the user object extended to UserProfile and cannot user the user.id
Is the request.user authenticated? is it an AnonymousUser?
UserProfile.objects.get() method is not for creating an object but to get it from the database.
if it doesn't exist an exception will be raised.
use UserProfile.objects.create(..) with the initial data you may need for it.
hope this helps!
== edit ==
also, note that you are referring count_form in the RequestContext even when it wasn't initialized in case that the request.method was not "POST" (i.e. "GET")

Categories

Resources