In my application pos, I have the following model::
class Receipt(Model):
class Meta:
db_table = 'pos_receipt'
I want to rename the table as pos_receipt_ghost and I don't want to hardcode the app name.
I want to do this:
class Receipt(Model):
class Meta:
db_table = '%s_receipt_ghost` % get_app_name()
Does something like get_app_name exists ?
Name of the app is available in Meta.app_label
class Receipt(Model):
class Meta:
pass
Receipt._meta.db_table = '%s_receipt_ghost' % Receipt._meta.app_label
Or
class Receipt(Model):
class Meta:
db_table = '%s_receipt_ghost'
Receipt._meta.db_table %= Receipt._meta.app_label
Related
This is my model:
class FeedSource(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
feed = models.ForeignKey(Feed, on_delete=models.CASCADE) #FIXME: Deletion
title = models.CharField(max_length=200)
show_on_frontpage = models.BooleanField(default=True)
tags = TagField()
def __str__(self):
return self.title
class Meta:
ordering = ["title"]
unique_together = (("user", "feed"))
And this is my attempt to get all tags in schema.py:
class TagType(DjangoObjectType):
class Meta:
model = tagulous.models.TagModel
# model = FeedSource
interfaces = (graphene.relay.Node,)
class Query(graphene.ObjectType):
all_tags = graphene.List(TagType, username=graphene.String(required=True))
def resolve_all_tags(self, info, **kwargs):
tags = FeedSource.tags.tag_model.objects.all()
return tags
In graphiql I get the error: Expected value of type \"TagType\" but got: Tagulous_FeedSource_tags."
How can I set the model so that GraphQL will work and I can retrieve a list of all my tags?
By default Tagulous auto-generates a unique tag model each time you use a TagField - here it has generated the model Tagulous_FeedSource_tags (also accessible as FeedSource.tags.tag_model), so you're referencing the abstract model instead of the specific tag model for your field.
Based on my understanding of graphene I'm guessing it's not happy with you using a base class and expects you to use the class itself - so although I've not tried this myself, I think the following should work:
class TagType(DjangoObjectType):
class Meta:
model = FeedSource.tags.tag_model
...
You can get all tags for a specific model type and TagField() on the model like this (with the TagField being tags in this case):
all_tags = FeedSource.tags.tag_model.objects.all()
I'm new to both Django and DRF. I need to expose the following JSON via GET, but I seem to be having trouble getting each class to be a part of classes []. I belive I can use StringRelatedField for this, but the examples I have found don't seem to click with me. Thanks in advance!
expected output
{
"classes":[
{
"id":24,
"name":"Math 101",
"starts_on":"2016-08-09",
"ends_on":"2016-08-14",
"entries_url":"https://example.com/classes/24/classes.json"
},
{
"id":23,
"name":"English 101",
"starts_on":"2016-07-28",
"ends_on":"2016-07-30",
"entries_url":"https://example.com/classes/23/classes.json"
}
]
}
Here's what I've cobbled together. "nr" is just a throwaway variable as I don't actually want any data besides what comes from class.
model.py
class Class(models.Model):
id = models.CharField(max_length=10)
starts_on = models.DateTimeField(auto_now_add=False)
ends_on = models.DateTimeField(auto_now_add=False)
entries_url = models.CharField(max_length=150)
class Meta:
ordering = ('id',)
class Classes(models.Model):
nr = models.CharField(max_length=100)
serializers.py
class ClassesSerializer(serializers.ModelSerializer):
class = serializers.StringRelatedField(many=True)
class Meta:
model = Classes
fields = ('classes')
Your database needs to keep a relation between your tables. You can use a foreign key here:
class Class(models.Model):
id = models.CharField(max_length=10)
starts_on = models.DateTimeField(auto_now_add=False)
ends_on = models.DateTimeField(auto_now_add=False)
entries_url = models.CharField(max_length=150)
related_classes = models.ForeignKey('Classes', on_delete=models.CASCADE, related_name='classes')
class Meta:
ordering = ('id',)
class Classes(models.Model):
nr = models.CharField(max_length=100)
Then, your serializer becomes:
class ClassSerializer(serializers.ModelSerializer):
class Meta:
model = Class
fields = ['__all__']
class ClassesSerializer(serializers.ModelSerializer):
classes = ClassSerializer(many=True)
class Meta:
model = Classes
fields = ('classes',)
Also, I strongly discourage you to use class for your variables, since it clashes with the class keyword of Python.
The code
I have these models :
class Activity(models.Model):
is_child_friendly = models.BooleanField()
free_wifi = models.BooleanField()
parking_avilable = models.BooleanField()
class RouteOrdering(models.Model):
route_id = models.ForeignKey(Route, on_delete=models.CASCADE)
activity_id = models.ForeignKey(Activity, on_delete=models.CASCADE, related_name='tracks')
day = models.IntegerField()
order = models.IntegerField()
class Meta:
ordering = ['order']
And these Serializers:
class ActivitySerializer(serializers.ModelSerializer):
class Meta:
model = Activity
class RouteOrderingSerializer(serializers.ModelSerializer):
class Meta:
model = RouteOrdering
fields = ('id','day','order','route_id','activity_id','tracks')
The problem
I want the RouteOrderingSerializer to return also the activity with the same activity_id. For this I thought I should use nested serializers.
What I've tried
I've tried adding a nested serializer like so:
activity = ActivitySerializer( read_only=True)
But this resulted no output in the endpoint. I know this is not the use case presented in the documentation, and this is probably why its noy working.
Ill be glad to see what code will work to get this done :)
I'm not sure why you got an error when you tried the following code. I assumed it was a bug related to the _id ending, but everything works fine when I run it.
class ActivitySerializer(serializers.ModelSerializer):
class Meta:
model = Activity
class RouteOrderingSerializer(serializers.ModelSerializer):
activity_id = ActivitySerializer( read_only=True)
class Meta:
model = RouteOrdering
fields = ('id','day','order','route_id','activity_id','tracks')
While you can, I don't recommend using a name ending in _id for a relation in Django. The issue is that Django internally stores all foreign keys under their <relation_name>_id. This allows various nice things, such as setting <object>.<relation_name>_id to an integer id and saving the object vs setting <object>.<relation_name> to the entire related object (which may require a db lookup to get in the first place). The one place I find this behaviour not intuitive is in serializers, where the default is to represent the relation as "<relation_name>": <id> instead of "<relation_name>_id": <id>, though you can explicitly declare the <relation_name>_id field and either remove or nest the <relation_name> field separately.
If you rename your relations to not have the trailing _id, the following will work:
class ActivitySerializer(serializers.ModelSerializer):
class Meta:
model = Activity
class RouteOrderingSerializer(serializers.ModelSerializer):
activity = ActivitySerializer( read_only=True)
class Meta:
model = RouteOrdering
fields = ('id','day','order','route_id','activity','tracks')
(Note that declaring route instead of route_id would be more in line with the default behaviour, but less clear in my opinion)
Try this:
class ActivitySerializer(serializers.ModelSerializer):
class Meta:
model = Activity
class RouteOrderingSerializer(serializers.ModelSerializer):
activity_id = ActivitySerializer()
class Meta:
model = RouteOrdering
fields = ('id','day','order','route_id','activity_id')
I would like to do something like the following:
models.py
class Container(models.Model):
size = models.CharField(max_length=20)
shape = models.CharField(max_length=20)
class Item(models.Model):
container = models.ForeignKey(Container)
name = models.CharField(max_length=20)
color = models.CharField(max_length=20)
class ItemSetting(models.Model):
item = models.ForeignKey(Item)
attribute_one = models.CharField(max_length=20)
attribute_two = models.CharField(max_length=20)
serializers.py
class ItemSettingSerializer(serializers.ModelSerializer):
class Meta:
model = ItemSetting
class ItemSerializer(serializers.ModelSerializer):
settings = ItemSettingSerializer(many=True)
class Meta:
model = Item
fields = ('name', 'color', 'settings')
class ContainerSerializer(serializers.ModelSerializer):
items = ItemSerializer(many=True)
class Meta:
model = Container
fields = ('size', 'shape', 'items')
When I do nesting of only one level (Container and Item) it works for me. But when I try to add another level of nesting with the ItemSetting, it throws an AttributeError and complains 'Item' object has no attribute 'settings'
What am I doing wrong?
Multiple nested serialization works for me. The only major difference is that I specify a related_name for the FK relationships. So try doing this:
class Item(models.Model):
container = models.ForeignKey(Container, related_name='items')
class ItemSetting(models.Model):
item = models.ForeignKey(Item, related_name='settings')
Hope this works for you.
I want to set the db_table Meta class attribute in a base class so that all inherited classes will have their names in it, similar to how Django treats related_name model field attribute:
class BaseModel(models.Model):
class Meta:
db_table = 'prefix_%(class)s'
So the inherited model:
class SubModel(BaseModel):
pass
will have db table prefix_submodel.
Is that possible? Can the Meta class access the inheriting class' model name?
No. You can't do that. It is not that simple to have same table to store for multiple classes.
What you need is probably djeneralize project.
From the examples:
class Fruit(BaseGeneralizedModel):
name = models.CharField(max_length=30)
def __unicode__(self):
return self.name
class Apple(Fruit):
radius = models.IntegerField()
class Meta:
specialization = 'apple'
class Banana(Fruit):
curvature = models.DecimalField(max_digits=3, decimal_places=2)
class Meta:
specialization = 'banana'
class Clementine(Fruit):
pips = models.BooleanField(default=True)
class Meta:
specialization = 'clementine'
which then allows the following queries to be executed:
>>> Fruit.objects.all() # what we've got at the moment
[<Fruit: Rosy apple>, <Fruit: Bendy banana>, <Fruit: Sweet
clementine>]
>>> Fruit.specializations.all() # the new stuff!
[<Apple: Rosy apple>, <Banana: Bendy banana>, <Clementine: Sweet
clementine>]