How to model a complex list in Flask - flask

My API is returning lists with three entries like so (pseudocode only)
results=[]
for db_row in db_rows:
result = []
result.append (db_row[0]) # Name (string)
result.append (db_row[1]) # Age (int)
result.append (db_row[2]) # DOB (timestamp)
results.append (results)
I want to create a model for it to show up in swagger docs like so
_results_model = api.model (
'results model',{
'results': fields.List(
fields.String(
description = 'Name of user',
min_length = 6,
max_length = 64,
pattern = '.*',
help = "...",
example = 'john.smith'
),
fields.Integer(
description = 'Age of user',
minimum=0,
help = "...",
example = '25'
),
fields.DateTime(
description = 'Date of birth',
help = "...",
example = '1918-11-11'
)
)
}
)
But it appears it is not possible to pass more than one parameter to fields.List
'results': fields.List
TypeError: __init__() takes 2 positional arguments but 4 were given
Question: What other option do I have for creating a model to represent a complex list?

Related

Select rows based on variable column name

This does not seem difficult, but I am stacked here.
I want to reference table column by variable name for filtering and cannot understand why this is not working.
let
Source = Table.FromRecords({
[VarColumn = "Val", Phone = "123-4567"],
[VarColumn = "Val2", Phone = "987-6543"],
[VarColumn = "NA", Phone = "543-7890"],
[VarColumn = "OTHER", Phone = "543-7890"]
}),
VariableColumn = "VarColumn",
filter = Table.SelectRows(Source, each (Table.Column(Source, VariableColumn) = "OTHER"))
in
filter
Try
filter = Table.SelectRows(Source, each Record.Field(_, VariableColumn) = "OTHER")

Django query to get List of Sums of the Count of different Choices

I am trying to get a list of the sum of the count of different choices. The choices are strings, so I want to count the same strings and get their sum, and then do the same for other choices. I made a query but it does not give me the total count of each choice instead list them all with the count 1.
model.py
class sublist(models.Model):
Music = 'Music'
Video = 'Video'
Gaming = 'Gaming'
News = 'News'
Lifestyle = 'Lifestyle'
Access = 'Access'
SUBTYPE_CHOICES =(
(Music , "Music"),
(Video , "Video"),
(Gaming , "Gaming"),
(News , "News"),
(Lifestyle , "Lifestyle"),
(Access , "Online Access"),
)
author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE,)
name = models.CharField(max_length=150)
cost = models.FloatField(default = 0)
subtype = models.CharField(max_length= 50, choices = SUBTYPE_CHOICES, default = Access)
This is my query. (i tried coming up with other combinations by looking at the documentation but no luck)
expenselist = sublist.objects.filter(author = curruser.id)
subtypecount = list((expenselist
.annotate(subcount=Count('subtype'))
.values('subtype', 'subcount')
))
result of query above: [{'subtype': 'Access', 'subcount': 1}, {'subtype': 'Access', 'subcount': 1},{'subtype': 'Video', 'subcount': 1}]
Desired result: [{'subtype': 'Access', 'subcount': 2},{'subtype': 'Video', 'subcount': 1}]
Here is the query that will produce your desired result.
First use .values() then .annotate()
subtypecount = sublist.objects.filter(author = curruser.id).values('subtype').annotate(subcount=Count('subtype'))
or
expenselist = sublist.objects.filter(author = curruser.id)
subtypecount = list(expenselist.values('subtype').annotate(subcount=Count('subtype')))

How do I add a default value to a nested serializer?

I am trying to have my "address" API return the default value (empty string ""), but when I use default="" in the serializer field it returns null instead.
This is my main serializer (LocationSerializer)
class LocationSerializer(serializers.ModelSerializer):
id = serializers.UUIDField(read_only=True)
business_id = serializers.PKRelatedField(Business.any.all(), "business")
city_id = serializers.UUIDField(required=True)
name = serializers.CharField(max_length=48, required=True)
tax_number = serializers.CharField(max_length=48)
phone = serializers.PhoneNumberField()
address = serializers.CharField()
address_details = AddressEmbeddedSerializer(default="", source="addresses")
footer = serializers.CharField()
is_active = serializers.BooleanField(required=True)
has_kds = serializers.BooleanField(read_only=True)
position = serializers.PointField()
image = serializers.ImageField()
# profile = LocationProfileSerializer()
permissions = PermissionSerializer(many=True, read_only=True)
payment_methods = PaymentMethodEmbeddedSerializer(many=True, read_only=True)
class Meta:
model = Location
fields = (
"id", "business_id", "city_id", "name", "tax_number", "phone", "address", "address_details", "footer",
"is_active", "has_kds", "position", "image", "permissions", "payment_methods"
)
and this is my nested serializer (AddressEmbeddedSerializer)
class AddressEmbeddedSerializer(serializers.ModelSerializer):
city = serializers.CharField(default="")
area = serializers.CharField(default="")
block = serializers.CharField(default="")
avenue = serializers.CharField(default="")
long = serializers.CharField(default="")
lat = serializers.CharField(default="")
class Meta:
model = LocationAddress
fields = (
"city", "area", "block", "avenue", "long", "lat"
)
The value that I am expecting is:
"address_details": {
"city": "",
"area": "",
"block": "",
"avenue": "",
"long": "",
"lat": ""
}
Instead what I am getting is:
"address_details": null
Please note that all CRUD operations are working, this is only a default value issue
The reason why "address_details": null is that the current object has no related addresses at a model object so the nested serializer won't be accessed and therefore your desired JSON output won't be generated.
Also, default is used when no value provided for the field with POST request not GET
I suggest that you handle address_details when it is null, but if you really need to do this you can do something at to_representation() or to_internal_value(), see this answer: https://stackoverflow.com/a/38606711/4984493
Also, you can use SerializerMethodField, so based on obj.addresses's value if it was null or not you return the desired JSON output you need.

Django aggregate queryset - combine the results of two querysets which both contain aggregates

I have the following model in django:
action = models.CharField("Action performed",max_length=200,db_index=True)
date = models.DateField("Date when event occured",blank=True)
time = models.TimeField("Time when event occured",blank=True)
timestamp = models.DateTimeField("Timestamp when event occured",blank=True,null=True,db_index=True)
username = models.ForeignKey(USER)
computer = models.ForeignKey(COMPUTER)
location = models.ForeignKey(LOCATION)
I wish to return data to a HTML page, which has the following columns:
COMPUTER NAME, COUNT(LOGON), COUNT(LOGOFF)
I am using
logOnOffData = LOGONOFF.objects.all()
computerBreakDown = logOnOffData.values("computer__computerName").annotate(Count("timestamp"))
This generates the number of occurrences of each computer being included in the database table. I can easily generate a queryset for each action, but cannot see how to include the results of the two querysets into one.
Would be wonderful to filter on annotations, somethink like:
loging_logut = ( Computer
.objects
.all()
.annotate( longons = Count( action__action = 'logon' ) )
.annotate( longouts = Count( action__action = 'logout' ) )
But this syntax is not allowed on django ORM. You can learn about it on FILTERING ON ANNOTATIONS IN DJANGO post.
In quoted article you can learn about some workaround: for example writing your own sql code in extra field.
If performance is not the issue, the most code readable approach is a dictionary like this:
{ 'john s computer': { 'n_logins': 100, 'n_logounts' :99 },
'mathiew s computer': { 'n_logins': 80, 'n_logouts' :80 },
...
}
To get this dictionary you can annotate logins and logouts separately, then join it:
#logons = { 'john s computer': 100, 'mathiew s computer': 80, ... }
logons = dict(
Computer
.objects
.filter( action__action = 'logon' )
.annotate( longons = Count( ) )
.values_list( 'name', 'logons' )
)
#logons = { 'john s computer': 99, 'mathiew s computer': 80, ... }
logouts = dict( ...
#joining dicsts
computers = {}
for computer in Computer.objects.all().values_list( 'name', flat = True):
computers[computer]['n_logins'] = logons[computer]
computers[computer]['n_logouts'] = logouts[computer]

List display names from django models

I have an object:
POP_CULTURE_TYPES = (
('SG','Song'),
('MV', 'Movie'),
('GM', 'Game'),
('TV', 'TV'),
)
class Pop_Culture(models.Model):
name = models.CharField(max_length=30, unique=True)
type = models.CharField(max_length=2, choices = POP_CULTURE_TYPES, blank=True, null=True)
Then I have a function:
def choice_list(request, modelname, field_name):
mdlnm = get.model('mdb', modelname.lower())
mdlnm = mdlnm.objects.values_list(field_name, flat=True).distinct().order_by(field_name)
return render_to_response("choice_list.html", {
'model' : modelname,
'field' : field_name,
'field_list' : mdlnm })
This gives me a distinct list of all the "type" entries in the database in the "field_list" variable passed in render_to_response. But I don't want a list that shows:
SG
MV
I want a list that shows:
Song
Movie
I can do this on an individual object basis if I was in the template
object.get_type_display
But how do I get a list of all of the unique "type" entries in the database as their full names for output into a template?
I hope this question was clearly described. . .
How about something like this at the end of your choice_list()?
def choice_list(request, modelname, field_name):
# ...
pct = dict(POP_CULTURE_TYPES)
return [pct[key] for key in mdlnm]
Or in one line w/o the dict() call:
return [pct[1] for pct in POP_CULTURE_TYPES if pct in mdlnm]
Not pretty but it will work until to run across something better.
You could use:
OBJECT.get_FIELD_display()
Example:
content = Pop_Culture.objects.get(...)
ctype = content.get_type_display()
There is no need for workarounds :)