Lets say I have a model A that has fields lat(FloatField) and lon(FloatField). I want to annotate the QuerySet using a point:
A.objects.annotate(point = Value(Point(F('lat'), F('lon')), output_field=PointField()))
I keep on getting TypeError('Invalid parameters given for Point initialization.')
For some reason Django is not recognizing the fields and instead is passing them as strings (I think).
How do I accomplish this?
Thanks
I personally believe you're better off writing a one time migration to add the point field rather than annotating this, but you are just passing strings ATM. You need to use F
A.objects.annotate(
point=ExpressionWrapper(
Point(F('lat'), F('lon')), output_field=PointField()))
ref: https://docs.djangoproject.com/en/3.0/ref/models/expressions/#using-f-with-annotations
Related
I have a 'Parts' model, and these parts are either linked to a 'Device' model or not yet. The actual "link" is done via more than just one ForeignKey, i.e. I have to go through 3 or 4 Models all linked between each other with ForeignKeys to finally get the data I want.
My question is: What is the most efficient way of getting both the linked and non-linked parts ?
Right now, I am getting all parts and simply outputting that, but I would like a little separation:
allParts = Parts.object.all()
I know I could do something similar to this:
allParts = Parts.object.all()
linkedParts = allParts.objects.filter(...device_id=id)
nonLinkedParts = allParts.objects.exclude(...device_id__in=[o.id for o in linkedParts])
But is that really the most efficient solution ? I feel like there would be a better way, but I have not yet found anything in the docs about it.
Just to clarify, there are only linked, and non-linked parts. These are mutually exclusive and exhaustive.
Thank you very much
If you are only interested in obtaining the elements, for example to iterate over it, you can work with two lists:
allParts = Parts.object.all()
linkedParts = []
nonLinkedParts = []
for part in allParts:
if part.device_id == id:
linkedParts.append(part)
else:
nonLinkedParts.append(part)
since these are lists, you can no longer (efficiently) filter further, or order by a specific condition. If you want to order it by a certain field, you should do that already in the allParts database query.
I have the following 2 lines of
CategoryContext = Somemodel.objects.values('title__categories__category').distinct()
CategoryContextSum = CategoryContext.annotate(Total_Revenue=Sum('revenue')).order_by('-Total_Revenue')
CategoryContextAvg = CategoryContext.annotate(Average_Revenue=Avg('revenue')).order_by('-Average_Revenue')
The avg query yields a querylist of objects where the category comes first, followed by the revenue. So basically:
<QuerySet [{'title__categories__category':'Category', 'Average_Revenue':Decimal('100'),}, {'title__categories__category':'Category2':'Average_Revenue':Decimal('120'), }]>
The sum query on the other hand yields the revenue followed by the category, so basically:
<QuerySet [{'Total_Revenue':Decimal('100'), 'title__categories__category':'Category'}, {'Total_Revenue':Decimal('120'), 'title__categories__category':'Category2'}]>
Now I have tried flipping the queries around and changing the variable names so far, but I cannot seem to figure out why in the heck these 2 statements are behaving so differently. Does anybody know what could influence annotation behavior in Django?
Edit:
In case you are wondering why I need to understand this: I am passing the queryset to a method that turns it into data for generating a barchart and the first object in the dataset must be the identifier of the value. I could make it so that it inverts the whole process by checking whether this indeed is the case and ivnerting otherwise, but it seems to me that this shouldnt be necessary
This has little or nothing to do with annotate. Dictionaries in Python have no conventional sense of ordering (at least not until Python 3.6), and keys can be ordered differently across different queryset results.
And this constitutes little or not problem since you'll be access required values by key and not serially (as with sequences):
for obj_dct in your_qs:
print(obj_dct[some_key])
If your plot function takes dicts, no need to worry about ordering.
I am wondering what is the best way to iterate over a Django QuerySet while deleting objects within the Queryset? For example, say you have a log table with entries at specific times, and you wanted to archive them so that there is no more than 1 entry every 5 minutes. I know this may be wrong, but this is kind of what I am going for:
toarchive = Log.objects.all().order_by("-date")
start = toarchive[0].date
interval = start - datetime.timedelta(minutes=5)
for entry in toarchive[1:]:
if entry.date > interval:
entry.delete()
else:
interval = entry.date - datetime.timedelta(minutes=5)
So I guess I have answered my own question by asking it, if anyone else is curious. I thought there would have been a problem when deleting objects while iterating over them, but there isn't. The code snippet in the question is the right way to do it.
Querysets have a delete method that will delete all the results of that queryset. For the example you gave
toarchive.filter(date__gt=interval).delete()
will work. If you're doing a test that can't be done in a filter, however, the method you described is probably best.
I'm really new to django programming, and I'm facing a problem I don't really know how to solve:
I want to get a list of users who have many string attributes, but only the users whom none of it's attributes is equal to a given one.
I have this piece of code
all_users = list(UserProfile.objects.attribute.filter(type=given).exists())
but this code will return me the users who have that attribute, so here's the question: How I can modify this line (or what lines do I need to add) in order to get the list of users without this attribute
Ps: Maybe I didn't explained myself clearly as I don't really know how to specify my problem in english, but, if you don't know what I'm asking I can try again
Thanks all
You can use exclude:
all_users = list(UserProfile.objects.attribute.exclude(type=given).exists())
To quote the docs:
To create such a subset, you refine the initial QuerySet, adding filter conditions. The two most common ways to refine a QuerySet are:
filter(**kwargs)
Returns a new QuerySet containing objects that match the given lookup parameters.
exclude(**kwargs)
Returns a new QuerySet containing objects that do not match the given lookup parameters.
We have a pretty long table where a row should be rendered using FormAlchemy.
The requirement is that the 'title' column should be displayed first and all other fields should follow in alphabetical order. Is there a straight forward way to move and sort fields in FormAlchemy. I need a generic solution here....is touching the FieldSet._render_fields OrderedDict appropriate?
Passing the include paramter to the configure function of the fieldset will allow you to set the order. Are you looking to set it programatically? If not you can do
fieldset.configure(include=[fieldset.title, fieldset.a_field, fieldset.b_field, fieldset.c_field])