I have a jsonfield in Postgres db and data like below:
income_info = [
{
"id": "1",
"name": "A",
"min_income": 22000
},
{
"id": "2",
"name": "B",
"min_income": 40000
},
{
"id": "3",
"name": "C",
"min_income": 22000
}
]
Now want to use gte and lte over the django orm queryset. Already tried
Employee.objects.filter(income_info__min_income__lte = 4000000)
but did not work at all.
models.py:
class Employee(models.Model):
institute = models.ForeignKey(Institute, on_delete=models.DO_NOTHING)
income_info = JSONField(default=list)
others = models.TextField(null=True)
In django's documentation for querying JsonFields:
If the key is an integer, it will be interpreted as an index lookup in an array
As your json data is list of json datas, you need a query like this:
Employee.objects.filter(income_info__0__min_income__lte=4000000)
Related
I have a Bookmark and a BookmarkCategory object. I'd like to be able to fetch JSON that looks like this:
GET -> localhost:8000/api/bookmarks
[
"python": {
"title": "Python",
"bookmarks": [
{
"title": "Python Documentation",
"url": "https://docs.python.org"
}
]
},
"javascript": {
"title": "Javascript",
"bookmarks": [
{
"title": "Python Documentation",
"url": "https://developer.mozilla.org/en-US/docs/Web/JavaScript"
}
]
}
]
Here's my models:
class BookmarkCategory(models.Model):
title = models.CharField(max_length=255)
class Bookmark(models.Model):
title = models.CharField(max_length=255)
url = models.CharField(max_length=255)
category = models.ManyToManyField(BookmarkCategory)
Here's how I would query all the BookmarkCategory objects:
from .models import BookmarkCategory
bookmarks = BookmarkCategory.objects.all()
The JSON doesn't have to look exactly like this. I just need to get all my BookmarkCategory objects along with all the related Bookmark objects so I can iterate over them after I make a GET request to fetch them.
You'll have to use select_related on "bookmark_set", to fetch them along. If you are using DRF, you need to create a nested serializer configuration for bookmarks. Here is an example without DRF:
categories = BookmarkCategory.objects.select_related("bookmark_set")
items = []
for category in categories:
items.append(
{
"title": category.title,
"bookmarks": category.bookmark_set.values_list("title", "url"),
}
)
1) I have a JSON file (structure as seen below) and it has hundreds of records. How can I put these data into my Django model so that I am able to perform CRUD operations on the data?
I do not want to change the structure of the JSON file to match the output given by Django's model files as it can be tedious.
2) Please advise as I am also unsure where to put my JSON files in the project as well.
[
{
"name": "A",
"abbreviation": "a",
"count": 1
},
{
"name": "B",
"abbreviation": "b",
"count": 3
},
{
"name": "C",
"abbreviation": "c",
"count": 55
}
.
.
.
]
I am new and using Django 2.2 and I just finished "TheNewBoston" Django tutorial. I am using Django's model to makemigration and migrate to my database. I think I am using SQLite which is the default for Django.
Below is my code for my model.
class userDetail(models.Model):
name = models.IntegerField(max_length=20)
abbreviation = models.CharField(max_length=2)
count = models.IntegerField()
EDIT:
I created a data migration apart from the 0001_initial.py.
class Migration(migrations.Migration):
initial = True
def load_data(apps, schema_editor):
data1 = [{
"id": "A",
"abbreviation": "a",
"count": 1
}]
for data in data1:
c = userDetail(id=data['id'],abbreviation=data['abbreviation'], count=data['count'])
c.save()
dependencies = [
'userDetail', '0001_initial.py',
]
operations = [
migrations.RunPython(load_data),
]
I have responce data from API it's look like this
{
"api": {
"results": 1,
"fixtures": {
"65": {
"fixture_id": "65",
"event_timestamp": "1533927600",
"event_date": "2018-08-10T19:00:00+00:00",
"league_id": "2",
"round": "Premier League - 1",
"homeTeam_id": "33",
"awayTeam_id": "46",
"homeTeam": "Manchester United",
"awayTeam": "Leicester",
"status": "Match Finished",
"statusShort": "FT",
"goalsHomeTeam": "2",
"goalsAwayTeam": "1",
"halftime_score": "1 - 0",
"final_score": "2 - 1",
"penalty": null,
"elapsed": "95",
"firstHalfStart": "1533927660",
"secondHalfStart": "1533931380"
}
}
}
}
Now I am trying to build fixture model to store above data in PosgreSql database. I dont understand didnt find any example of builded model with timestamptz field. I need to store event_date key in timestamptz. Can anyone to show me how i should create this field
Django does not have a default timestamp field. However, you can add one by having the following model field:
event_date = models.DateTimeField(auto_now_add=True)
EDIT
Or alternatively, something a little more up to date:
from django.utils import timezone
....
event_date = models.DateTimeField(default=timezone.now)
Make sure its timezone.now and not timzone.now()
I have the following situation
class MyModel(models.Model):
key = models.CharField(max_length=255)
value = models.TextField(max_length=255)
category = models.CharField(max_length=4)
mode = models.CharField(max_length=4)
the fields key, category and mode are unique together. I have the following objects:
m1 = MyModel(key='MODEL_KEY', value='1', category='CAT_1' mode='MODE_1')
m2 = MyModel(key='MODEL_KEY', value='2', category='CAT_1' mode='MODE_2')
m3 = MyModel(key='MODEL_KEY', value='1', category='CAT_2' mode='MODE_1')
m4 = MyModel(key='MODEL_KEY', value='2', category='CAT_2' mode='MODE_2')
I want to expose an API that will group by key and category so the serialized data will look something like this:
{
"key": "MODEL_KEY",
"category": "CAT_1"
"MODE_1": { "id": 1, "value": "1" }
"MODE_2": { "id": 2, "value": "2" }
},
{
"key": "MODEL_KEY",
"category": "CAT_2"
"MODE_1": { "id": 3, "value": "1" }
"MODE_2": { "id": 4, "value": "2" }
}
Is there any way of doing this in django rest framework with ModelSerializer.
There is module that allows you to group Django models and still work with a QuerySet in the result: https://github.com/kako-nawao/django-group-by
Using the above to form your queryset:
# Postgres specific!
from django.contrib.postgres.aggregates.general import ArrayAgg
qs = MyModel.objects.group_by('key', 'category').annotate(
mode_list=ArrayAgg('mode')).order_by(
'key', 'category').distinct()
You can then access the properties key, category and mode_list on the resulting QuerySet items as attributes like qs[0].mode_list. Therefore, in your serializer you can simply name them as fields.
The model_list field might require a SerializerMethodField with some custom code to transform the list.
Note that you need an aggregation if you don't want to group by mode, as well.
So I have a Film model that holds a list of Actors model in a many to many field:
class Person(models.Model):
full = models.TextField()
short = models.TextField()
num = models.CharField(max_length=5)
class Film(models.Model):
name = models.TextField()
year = models.SmallIntegerField(blank=True)
actors = models.ManyToManyField('Person')
I'm trying to load some initial data from json fixtures, however the problem I have is loading the many to many actors field.
For example I get the error:
DeserializationError: [u"'Anna-Varney' value must be an integer."]
with these fixtures:
{
"pk": 1,
"model": "data.Film",
"fields": {
"actors": [
"Anna-Varney"
],
"name": "Like a Corpse Standing in Desperation (2005) (V)",
"year": "2005"
}
while my actors fixture looks like this:
{
"pk": 1,
"model": "data.Person",
"fields": {
"full": "Anna-Varney",
"num": "I",
"short": "Anna-Varney"
}
}
So the many to many fields must use the pk integer, but the problem is that the data isn't sorted and for a long list of actors I don't think its practical to manually look up the pk of each one. I've been looking for solutions and it seems I have to use natural keys, but I'm not exactly sure how to apply those for my models.
EDIT: I've changed my models to be:
class PersonManager(models.Manager):
def get_by_natural_key(self, full):
return self.get(full=full)
class Person(models.Model):
objects = PersonManager()
full = models.TextField()
short = models.TextField()
num = models.CharField(max_length=5)
def natural_key(self):
return self.full
But I'm still getting the same error
There's a problem with both the input and the natural_key method.
Documentation: Serializing Django objects - natural keys states:
A natural key is a tuple of values that can be used to uniquely
identify an object instance without using the primary key value.
The Person natural_key method should return a tuple
def natural_key(self):
return (self.full,)
The serialised input should also contain tuples/lists for the natural keys.
{
"pk": 1,
"model": "data.film",
"fields": {
"actors": [
[
"Matt Damon"
],
[
"Jodie Foster"
]
],
"name": "Elysium",
"year": 2013
}
}