Django: update with conditions - python

I want to update an object through a form in Django but before doing form.save() in the view I want to do some conditions about the data.
For example:
ire = get_object_or_404(Ire, id_IRE=pk)
if request.method == 'POST':
form = IreForm(request.POST or None, instance=ire)
if form.is_valid():
if ire.get_att1()==form.cleaned_data.get('att1') and ire.get_att2()==form.cleaned_data.get('att2'):
form.save(update_fields=['type']) #just update the field type
else:
form.save() #create a new object
When I did this in my view just the first condition works but when I change the att1 or att2 in the form it does not do any changes.
Please help me how can I do conditions before saving!!!

thank you i found the solution which is storing the values of the object that i want to update befor doing the update operation :
ire = get_object_or_404(Ire, id_IRE=pk)
**ire_att1=ire.get_att1()**
**ire_att2=ire.get_att2()**
**ire_type=ire.get_type()**
if request.method == 'POST':
form = IreForm(request.POST or None, instance=ire)
if form.is_valid():
if **ire_att1**==form.cleaned_data.get('att1') and **ire_att2**==form.cleaned_data.get('att2'):
Ire.objects.filter(id_IRE=pk).update(type=form.cleaned_data.get('type'))
else:
form.save()
this is how i solve the probleme because i found that after calling the form model the values of the object change simultaneously with what i enter even before i call form.save

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.

How to loop over a queryset for instantiate all formset?

I wish I could make a loop that would allow me to instantiate all my formsets for now I have written
def access(request, page_id):
if request.method == 'POST':
formset = ReplyFormSet(request.POST, request.FILES, initial=[{'instance':instance,}])
if formset.is_valid():
#...
return ...
else:
formset = ReplyFormSet(queryset=Reply.objects.filter(question=questions))
return ...
On this last line that I recovered the information in the db but just for my first forms! Is there way to make a loop so that it instantiates me all the forms?
I tried something like this but it does not work :
else:
for form in formset:
form.formset = ReplyFormSet(queryset=Reply.objects.filter(question=questions))
return ...
This line only works for my first form :
formset = ReplyFormSet(queryset=Reply.objects.filter(question=questions))
How can I do to affect it at all?
Should I change my init function of my ReplyForm ?
You could try:
formset = ReplyFormSet(queryset=Reply.objects.filter(question__in=questions))
Using the in filter you get every question which is in questions queryset.

2 forms, 1 view, 2 SQL tables in Django

I'm struggling to understand how to submit data from two django forms into two separate database tables from the same view. I only want one submit button. While this question got me closer to the solution, I'm getting errors and the data is not writing to the database. I think this code actually checks the two forms against each other instead of submitting both forms in one go. Any ideas?
Here's what I've tried:
For one form --> one table. This works, so it's a start.
# views.py
def BookFormView(request):
if request.method == 'POST':
form = BookForm(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect("/books/")
else:
form = BookForm()
return render(request, 'books/createbooks.html',
{'form' : form})
However, when I add this form in from forms.py to get the subsequent views.py I get local variable 'book_form' referenced before assignment. That's usually an easy global-vs-local variable issue to fix, but I don't know what it means in this case.
def BookFormView(request):
if request.method == 'POST':
if 'book' in request.POST:
book_form = BookForm(request.POST, prefix='book')
if book_form.is_valid():
book_form.save()
return HttpResponseRedirect("/books/")
bookdetailsform = BookDetailsForm(prefix='bookdetails')
elif 'bookdetails' in request.POST:
bookdetailsform = BookDetailsForm(request.POST, prefix='bookdetails')
if bookdetailsform.is_valid():
bookdetailsform.save()
return HttpResponseRedirect("/books/")
book_form = BookForm(prefix='book')
else:
book_form = BookForm(prefix='book')
bookdetailsform = BookDetailsForm(prefix='bookdetails')
return render(request, 'books/createbook.html',
{'book_form' : book_form,
'bookdetailsform': bookdetailsform})
Based on the question's comments:
def BookFormView(request):
if request.method == 'POST':
book_form = BookForm(request.POST, prefix='book')
bookdetailsform = BookDetailsForm(request.POST, prefix='bookdetails')
if book_form.is_valid() and bookdetailsform.is_valid():
book_form.save()
bookdetailsform.save()
return HttpResponseRedirect("/books/")
else:
book_form = BookForm(prefix='book')
bookdetailsform = BookDetailsForm(prefix='bookdetails')
return render(request, 'books/createbook.html',
{'book_form': book_form, 'bookdetailsform': bookdetailsform})
I think the problem is that when a user submits a bookdetails post request,
it will be handled under if 'book' in request.POST: condition. Why?
because string bookdetails contains string book, no matter the type of request they do, it will be handled with if book in request.POST: condition.
I believe fixing that if condition problem is the first step.

submitting two forms one after another

I am working on my first django webaite, I am trying to submit two forms one after the other.
Here is the views.py :
def home(request):
import json
if request.method == 'POST':
form = MajorForm(request.POST)
if form.is_valid():
url = 'http://www.mysite.com:8082'
dataout = {'my':'data'}
headers = {'content-type':'application/json'}
r = requests.post(url,data=json.dumps(dataout),headers=headers)
return collector(request)
else:
return HttpResponse("thnx")
else:
form = MajorForm()
return render(request,'index.html',{'form':form})
def collector(request):
if request.method == 'POST':
form = ContactForm(request.POST)
if form.is_valid():
return HttpResponse("thanx")
else:
return HttpResponse("not valid")
else:
form = ContactForm();
return render(request,'collector.html',{'form':form})
So the first view calls the second view. The first form works fine, and the second form is also displayed fine, but submitting the second form does not work at all ( I was never able to get to form.is_valid path). Maybe this entire approach of calling one view from another is not correct? What would be the right one?
Please indent your code correctly. Also you are missing an else in the collector function when the request.method is not POST.

Get Django Auth "User" id upon Form Submission

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

Categories

Resources