I have PATCH button form on ModelViewSet
class CompanyViewSet(viewsets.ModelViewSet):
serializer_class = s.CompanySerializer
queryset = m.Company.objects.all()
def patch(self, request, id, format=None):
print(id)
Now I try to modify the existing data id = 1
So I write this in textarea and push PATCH button.
{
"id":1,
"name": ""
}
However , there comes error like
patch() missing 1 required positional argument: 'id'
Maybe my json is wrong?? How can I do PATCH?
patch() missing 1 required positional argument: 'id'
Use perform_update like this :
class CompanyViewSet(viewsets.ModelViewSet):
serializer_class = s.CompanySerializer
queryset = m.Company.objects.all()
def perform_update(self, serializer):
instance = serializer.instance
request = self.request
serializer.save(**modified_attrs)
return Response(status=status.HTTP_200_OK)
I am using Karate for my test scenarios for the requirement to update the contract plan by passing the plan Id's and I am retrieving the planId from the database and passing it to my request json.
But the problem I am facing it comes with the column name whereas I only need the value.
Below is the example of how I am fetching my Id by connecting to the database
`#Scenario1
Scenario:
use jdbc to validate
def config = { username: 'mmultapp', password: 'Mmu1t#pp', url: 'jdbc:db2://edb2dev3.momentum.co.za:60022/MMULTTST', driverClassName: 'com.ibm.db2.jcc.DB2Driver' }
def DbUtils = Java.type('wellness_core_utils.DbUtils')
def db = new DbUtils(config)
def productId = db.readRows('select PRODUCT_ID from MULTUSR1.PLANS order by PLAN_ID desc fetch first 1 rows only')
print productId`
And I am getting the results in this way
{
"PRODUCT_ID": 68
}
I only need to read the value of 68 so I that I can pass it to my json request
Thanks in advance
The query returns a key-value pair which you write in the query, Suppose you write
select PRODUCT_ID AS pId from MULTUSR1.PLANS order by PLAN_ID desc fetch first 1 rows only;
So It returns a PRODUCT_ID with the name pId. Later on, you can use that result as per your requirements
Let's try this in your instance.
def productId = db.readRows('select PRODUCT_ID from MULTUSR1.PLANS order by PLAN_ID desc fetch first 1 rows only').PRODUCT_ID;
const result = productId.PRODUCT_ID;
Notice: Please check the first type of your query result
Like It's in [] or {}
In above instance I consider it in {}
const result = [{ PRODUCT_ID: 87 }];
console.log(result[0].PRODUCT_ID);
I have three models :
class Instances(models.Model):
name_of_instances = models.CharField(max_length=255)
url_of_instances=models.URLField(max_length=255,default='')
def __str__(self):
return self.name_of_instances
class Projects(models.Model):
name_of_instances = models.ForeignKey(Instances,on_delete=models.CASCADE)
name_of_jproject = models.CharField(max_length=255)
project_id= models.CharField(max_length=25)
def __str__(self):
return self.name_of_project
class All(models.Model):
choices_instance=Instances.objects.all()
b = [str(i.name_of_instances) for i in choices_instance]
a=[str(i.url_of_instances) for i in choices_instance]
choices_instance=tuple(zip(a,b))
name = models.CharField(max_length=255,choices=choices_instance)
project = models.CharField(max_length=255,)
story = models.CharField(max_length=500)
depends_on = models.CharField(max_length=500, default='')
rfc = models.CharField(max_length=255)
def __str__(self):
return self.name
I have a models form:
class Form(ModelForm):
class Meta:
model = All
fields =('name','project','story','depends_on','rfc')
In template, I want to know what user has drop down in 'name' field , and I want to send the name value to back end function where I will filter out all the projects associated with name value, and send the result to 'project' field as choices (drop down).
i got the solution using java script and ajax on the template
I am relatively new to Django framework and working on getting my first application running. I am encountering the below issue when i try to pass my queryset from my view to the template.
My view.py:
with connection.cursor() as cursor:
cursor.execute("SELECT TOP(5) * FROM xxx WHERE sbu = %s", [sbu])
def dictfetchall(cursor):
columns = [col[0] for col in cursor.description]
return [dict(zip(columns,row)) for row in cursor.fetchall()]
results = dictfetchall(cursor)
class DecimalEncoder(json.JSONEncoder):
def _iterencode(self, o, markers=None):
if isinstance(o, decimal.Decimal):
return (str(o) for o in [o])
return super(DecimalEncoder, self)._iterencode(o, markers)
json_result = json.dumps(data, cls=DecimalEncoder)
I end up with the below error:
Decimal('28.80') is not JSON serializable
Any suggestions? Am i missing a step somwhere? I have lot of decimal values in the queryset.
I have a javascript application (in angular) that calls my django application. It uses lists of integers to filter the response. In Django I'm using a form to clean the data.
Javascript:
app.factory('SearchData',
function(){
return {
shop:[],
sort:'',
xhr:'',
brand:[],
};
});
app.factory('SearchQuery',
['$http', '$location', '$route', 'SearchData',
function($http, $location, $route, SearchData){
return {
getItems: function(){
return $http.get('/search/',{
params: SearchData,
responseType: 'json',
});
}
};
}
]);
Python form:
class SearchForm(forms.Form):
shop = forms.IntegerField(widget=forms.SelectMultiple(),required=False)
sort = forms.CharField(max_length=1, min_length=1, required=False)
brand = forms.IntegerField(widget=forms.SelectMultiple(),required=False)
I get a list of integers in shop and brand but I do not how to handle it on the django side. I don't want to use MultipleChoiceField as I need to supply choices in form (which creates an unnecessary query). All I want to do is have a list of integers.
The form above throws "Enter a whole number.". I could just ditch the form and use request.GET.getlist('shop') (which works). But I'd rather use a form if possible...
Update, for now I'm using a MultipleChoiceField and pass the choices before validation in the view. Like:
shops = request.GET.getlist('shop', None)
sf = SearchForm(request.GET)
sf.fields['shop'].choices = shops
It works, but it isn't pretty.
Use a custom widget/field:
from django import forms
from django.core.exceptions import ValidationError
class MultipleValueWidget(forms.TextInput):
def value_from_datadict(self, data, files, name):
return data.getlist(name)
class MultipleValueField(forms.Field):
widget = MultipleValueWidget
def clean_int(x):
try:
return int(x)
except ValueError:
raise ValidationError("Cannot convert to integer: {}".format(repr(x)))
class MultipleIntField(MultipleValueField):
def clean(self, value):
return [clean_int(x) for x in value]
class SearchForm(forms.Form):
shop = MultipleIntField()
You can use TypedMultipleChoiceField from Django forms with coerce=int and to avoid validation against predefined list of choices override the def valid_value(self, value): method:
class MultipleIntegersField(forms.TypedMultipleChoiceField):
def __init__(self, *args, **kwargs):
super(MultipleIntegersField, self).__init__(*args, **kwargs)
self.coerce = int
def valid_value(self, value):
return True
class SearchForm(forms.Form):
shop = MultipleIntegersField()
Udi's code is good, but there is a problem (under Django 1.11.7) if you want to use this as (say) a hidden field of a completely general user-input form. The problem is that if the user input fails to validate and is re-POSTed with corrections, the multi-valued POST data comes back the second time around as a repr of itself, i.e
['a','b'] comes back as ["['a', 'b']"] and further mangled with each re-POST
So I wrote the following function which can be used to repair the damage every time the view processes POST data. It's a hack, because it involves making request.POST temporarily mutable using a private variable. Also it doesn't properly handle lists of strings containing commas, escaped quotes etc.
def sanitize_keys( request, only=None):
""" Restore multi-valued keys that have been re-posted. there's a repr
in the round trip, somewhere.
only = list of keys to sanitize. Default is all of them."""
mutt = request.POST._mutable
request.POST._mutable = True
keylist = only or request.POST.keys()
for key in keylist:
v = request.POST.get(key)
if v.startswith("[") and v.endswith("]"):
#print( "Debug: sanitizing " + v )
sanitized=[]
for s in v[1:-1].split(','):
s = s.strip()
if s.startswith("'") and s.endswith("'"):
s=s[1:-1].replace("\\'","'")
sanitized.append(s)
#print( "Debug: sanitized= ", sanitized )
request.POST.setlist( key, sanitized)
request.POST._mutable = mutt
return
Usage (fragments):
class TestForm( forms.Form):
name = forms.CharField()
...
customer_iid = MultipleValueField( required=False)
...
# POST
sanitize_keys( request, only=('customer_iid',) )
#print( 'Debug: customer_iid', request.POST.getlist('customer_iid', []) )
form = TestForm( request.POST)