when i try to insert data to my database through manage.py shell, i got this error
ValueError: Cannot assign "'Ciawigebang'": "Desa.kecamatan" must be a "Kecamatan" instance.
this is my models.py
from django.db import models
class Kecamatan(models.Model):
kecamatan = models.CharField(max_length=30)
def __str__(self):
return self.kecamatan
class Desa(models.Model):
desa = models.CharField(max_length=30)
kecamatan = models.ForeignKey(Kecamatan, null=True, blank=True, on_delete=models.CASCADE)
def __str__(self):
return self.desa
here my json file snippet scrap.json
[
{
"Kecamatan": "Ciawigebang",
"Desa": [
"Ciawigebang",
"Ciawilor",
"Cigarukgak",
"Cihaur",
"Cihirup",
"Cijagamulya",
"Cikubangmulya",
"Ciomas",
"Ciputat",
"Dukuhdalem",
"Geresik",
"Kadurama",
"Kapandayan",
"Karangkamulya",
"Kramatmulya",
"Lebaksiuh",
"Mekarjaya",
"Padarama",
"Pajawanlor",
"Pamijahan",
"Pangkalan",
"Sidaraja",
"Sukadana",
"Sukaraja"
]
},{
"Kecamatan": "Cibeureum",
"Desa": [
"Cibeureum",
"Cimara",
"Kawungsari",
"Randusari",
"Sukadana",
"Sukarapih",
"Sumurwiru",
"Tarikolot"
]
},{
"Kecamatan": "Cibingbin",
"Desa": [
"BANTAR PANJANG",
"CIANGIR",
"Cibingbin",
"Cipondok",
"CISAAT",
"Citenjo",
"DUKUHBADAG",
"Sindang Jawa",
"SUKA MAJU",
"SUKAHARJA"
]
}...
]
this is the code i use to insert the data to database from python manage.py shell
import json
from apps.models import Desa, Kecamatan
with open('scrap.json') as f:
daerahs = json.load(f)
for daerah in daerahs:
for x in daerah['Desa']:
y=Desa(desa=x, kecamatan=daerah['Kecamatan'])
y.save()
how to solve this? there's so many similar question but i can't figure it out how to solve this problem in my case. Thanks for your help...
You need to create a Kecamatan instance. Change your code to this
for daerah in daerahs:
kecamatan, created = Kecamatan.objects.get_or_create(kecamatan=daerah['Kecamatan'])
for x in daerah['Desa']:
y = Desa(desa=x, kecamatan=kecamatan)
y.save()
follow this link to understand get_or_create
you need to use loaddata from your terminal python manage.py loaddata scrap.json
the format for the loaded data should be like this:
[
{
"pk": 1,
"model": "app.desa",
"fields": {
"kecamatan": 1,
"desa": "Ciawigebang"
},
{
"pk": 2,
"model": "app.desa",
"fields": {
"kecamatan": 1,
"desa": "Ciawigebang"
}
]
for every instance of Desa you provide a unique id and for the field kecamatan you use it's id since its a foriegn key (you need to populate the Kecamatan model with values, before populating the Desa models.)
meaning you should initially create another json file for Kecamatan, and load with with loaddata
[
{
"pk": 1,
"model": "app.kecamatan",
"fields": {
"kecamatan": "Ciawigebang",
},
{
"pk": "Cibeureum",
"model": "app.kecamatan",
"fields": {
"kecamatan": 1,
}
]
NOTE: app should be the name of your app that the Desa and Kecamatan models reside.
Related
I am a beginner who is learning Django using wagtail. I have a custom API model where I need to do 2 queries. I tried to return 2 queries at the same time with this code
def get_queryset(self):
return super().get_queryset().order_by('-first_published_at'), super().filter_queryset('story_type=Story')
and I am getting Attribute error 'str' object has no attribute 'model'
Here is my api.py
class ProdPagesAPIViewSet(BaseAPIViewSet):
renderer_classes = [JSONRenderer]
filter_backends = [FieldsFilter,
ChildOfFilter,
AncestorOfFilter,
DescendantOfFilter,
OrderingFilter,
TranslationOfFilter,
LocaleFilter,
SearchFilter,]
meta_fields = ["type","seo_title","search_description","first_published_at"]
body_fields = ["id","type","seo_title","search_description","first_published_at","title"]
listing_default_fields = ["type","seo_title","search_description","first_published_at","id","title","alternative_title","news_slug","blog_image","video_thumbnail","categories","blog_authors","excerpt","content","content2","tags","story_type"]
nested_default_fields = []
def get_queryset(self):
return super().get_queryset().order_by('-first_published_at'), super().filter_queryset('story_type=Story')
name = "stories"
model = AddStory
api_router.register_endpoint("stories", ProdPagesAPIViewSet)
With the order_by I am getting newest published stories first But I also want to filter story_type=Story. If I query this using URL then it works fine like ?story_type=Story
Here is the API response with the order_by query
{
"id": 5,
"meta": {
"type": "blog.AddStory",
"seo_title": "",
"search_description": "",
"first_published_at": "2022-09-19T23:27:12.895017Z"
},
"title": "Test Story",
"alternative_title": "Alternative Heading",
"blog_image": {
"id": 1,
"meta": {
"type": "wagtailimages.Image",
"detail_url": "http://localhost/api/v2/images/1/",
"download_url": "/127.0.0.1/media/original_images/tiktok_U4POKiL.jpeg"
},
"title": "tiktok"
},
"excerpt": "Test Excerpt",
"content": "<div class=\"block-full_richtext\"><p data-block-key=\"h053a\"> Test Story </p></div>",
"tags": [
"Test"
],
"news_slug": "eea1awauwc",
"story_type": "Story"
}
What I want is to filter story_type=Story & order_by('-first_published_at') at a same time, How can I do that?
Thanks a lot for reading.
def get_queryset(self):
return super().get_queryset().filter('story_type=Story').order_by('-first_published_at')
I'm currently a bit stuck. I have to create a model of our dynamodb using pynamodb, and here's what I have (part of a bigger model, exported from a real user in DB)
packs = [
{
"exos": {
"4": {
"start": 1529411739,
"session": 1529411739,
"finish": 1529417144
},
"5": {
"start": 1529417192,
"session": 1529417192
}
},
"id": 10
},
{
"exos": {
"32": {
"start": 1529411706,
"session": 1529411706
}
},
"id": 17
}
]
Here's what I got so far:
class ExercisesMapAttribute(MapAttribute):
pass
class PackMapAttribute(MapAttribute):
exos = ExercisesMapAttribute()
id = NumberAttribute()
class TrainUser(Model):
class Meta:
table_name = 'TrainUser'
region = 'eu-west-1'
# [...] Other stuff removed for clarity
packs = ListAttribute(of=PackMapAttribute())
Currently I think I got correctly up until the "4":, "5": etc... As they are exercices name.
The idea is that this structure is supposed to represent a list of packs, then inside a list of exercises with their id and more info... I need a way to map that from the current db json to classes I can then use with PynamoDB. Is it even possible?
Thanks!
I've tried DynamicMapAttribute but I can't figure out if it will work with my configuration.
I also don't know how a custom attribute could be done to overcome this.
I am parsing a file and end up with a dictionary like this:
user_data = {
"title": "TestA",
"sects": [
{
"type": "cmd",
"cmd0": {
"moveX": 12,
"moveY": 34,
"action": "fire"
},
"session": 9999,
"cmd1": {
"moveX": 56,
"moveY": 78,
"action": "stop"
},
"endType": 0,
},
{
"type": "addUsers",
"user1": {
"name": "John",
"city": "London"
},
"user2": {
"name": "Mary",
"city": "New York"
},
post = "yes"
}
]
}
I am attempting to validate it using marshmallow but not sure how to handle these two things:
With sects the content of each nested dict is dependent on the type (cmd, addUser, etc). Is there a way to pick a schema based on the value of a field?
Is there such a thing as field 'startsWith' to handle the fact that I may have cmd0, cmd1...cmdN?
So, something like the following:
class CmdSchema(schema):
type = fields.Str()
cmdN = fields.Dict(...) # Allow cmd1, cmd2, etc
session = fields.Int()
endType = fields.Int()
class AddUsersSchema(schema):
type = fields.Str()
userN = fields.Dict(...) # Allow user1, user2, etc
post = fields.Str()
class ParsedFileSchema(schema):
title = fields.Str()
sects = fields.Nested(...) # Choose nested schema based on sects[i]['type']?
Note: I cannot change the format/content of the file I'm parsing and order matters (so I need to retain the order of cmd1, cmd2, etc so they can be processed in the correct order).
1/ What you want to achieve is polymorphism. You may want to check out marshmallow-oneofschema.
2/ This does not exist to my knowledge. It shouldn't be too hard to create as a custom validator, though. It might even make it to the core.
I have a Textfield in my model which stores dictionaries, I would like to convert this field into a dictionary if possible in a rest serializer.
at the moment the field returns the dictionary but backslashes all the quotes, it is possible to convert the strings into a nested list of dicts?
Thanks
api currently returns below:
{
"id": 3,
"hostname": "WAN-EDGE",
"timestamp": "2019-04-12T11:34:36.654521",
"routing_table": "[{\"route\": \"0.0.0.0\", \"subnet_mask\": \"0.0.0.0\", \"next_hop\": \"172.16.66.193\"}, {\"route\": \"10.10.21.0\", \"subnet_mask\": \"255.255.255.0\", \"next_hop\": \"172.16.67.146\"}, {\"route\": \"10.22.0.0\", \"subnet_mask\": \"255.255.0.0\", \"next_hop\": \"172.18.1.5\"}, {\"route\": \"10.31.0.0\", \"subnet_mask\": \"255.255.0.0\", \"next_hop\": \"172.16.67.146\"},...]"
},...
}
desired result a nested list of dicts
{
"id": 3,
"hostname": "WAN-EDGE",
"timestamp": "2019-04-12T11:34:36.654521",
"routing_table": [
{
"route": "0.0.0.0",
"subnet_mask": "0.0.0.0",
"next_hop": "172.16.66.193"
},
{
"route": "10.10.21.0",
"subnet_mask": "255.255.255.0",
"next_hop": "172.16.67.146"
},
{
"route": "10.22.0.0",
"subnet_mask": "255.255.0.0",
"next_hop": "172.18.1.5"
},
{
"route": "10.31.0.0",
"subnet_mask": "255.255.0.0",
"next_hop": "172.16.67.146"
},...
]
},...
}
Current serialiser:
class RoutingTableSerializer(serializers.ModelSerializer):
hostname = serializers.ReadOnlyField(
source='device.hostname',
)
rt = serializers.JSONField(
source='routing_table'
)
class Meta:
model = DeviceData
fields = ('id','hostname','timestamp','rt')
You may need serializers.JSONField()
Update-1
You could also try with SerializerMethodField() as
import json
class RoutingTableSerializer(serializers.ModelSerializer):
hostname = serializers.ReadOnlyField(source='device.hostname', )
rt = serializers.SerializerMethodField(source='routing_table', read_only=True)
def get_routing_table(self, instance):
return json.loads(instance.routing_table)
class Meta:
model = DeviceData
fields = ('id', 'hostname', 'timestamp', 'rt')
Curently I have a viewset of an example Warehouse and I want to pass additional 'filter' list to each dictionary that is returned.
My WarehouseViewSet:
class WarehouseViewSet(viewsets.ReadOnlyModelViewSet):
filters = [{'date': 'Date/Time'}]
queryset = Warehouse.objects.all()
serializer_class = WarehouseSerializer
WarehouseSerializer:
class WarehouseSerializer(serializers.ModelSerializer):
class Meta:
model = Warehouse
field = ('name', 'address', 'action_list')
Currently I get an json list response like:
[
{
"id": 1,
"name": "Brameda Warehouse",
"address": "Bergijk"
},
{
"id": 2,
"name": "Amazon",
"address": "UK"
}
]
I would like to get:
[
{
"id": 1,
"name": "Brameda Warehouse",
"address": "Bergijk"
"filters": [
{'date': 'dateTime'}, {'actove': 'ActiveObject'}
]
},
{
"id": 2,
"name": "Amazon",
"address": "UK",
"filters": [
{'date': 'dateTime'}, {'actove': 'ActiveObject'}
]
}
]
I understand that having one filter is enough outside the objects dictionary, but I would like to know how to pass lists inside objects.
Any ideas how I can pass additional lists that would be returned as json object would be appreaciated.
I feel a bit unclear as to what you want, but if you just want to add some read-only computed field to the output, you can use SerializerMethodField:
class WarehouseSerializer(serializers.ModelSerializer):
# your other declared fields here
filters = serializers.SerializerMethodField()
# your Meta options here
def get_filters(self, obj):
return ['some', 'stuff', 'here', {'and': 'more'}]
The method has to be named get_field_name (there is an option to change it but I don't really see any point using it).
You get the instance being serialized as obj.
You may return anything that is made of regular types (numbers, strings, dicts, lists, tuples, booleans, None).
If the data has to come from outside, you should have the caller add it to the context, and it will be available on self.context['foobar'].