Django Tastypie can save related objects even with reverse relationship.
But is it able for Django Tastypie to save reverse relationship of GenericForeignKeyField?
My resources (not full, but the important only),
class AreaResource(ModelResource):
tripl3user = fields.ManyToManyField(
'tripl3sales.api.resources.area.Tripl3UserResource',
'tripl3user',
related_name='area',
full=True
)
class Tripl3UserResource(ModelResource):
content_type = fields.ForeignKey(
'tripl3sales.api.resources.contenttype.ContentTypeResource',
'content_type'
)
content_object = GenericForeignKeyField({
Area : AreaResource
}, 'content_object')
My models.py,
class Area(models.Model):
name = models.CharField(max_length=50, unique=True)
tripl3user = generic.GenericRelation('Tripl3User')
class Tripl3User(models.Model):
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
content_object = generic.GenericForeignKey('content_type', 'object_id')
Is it possible to save reverse relationship of generic foreign key? If so, then how to do it? What does the data look like?
Finally I got the answer.
In a resource that has content_type and object_id, there is no need to declare content_type because content_object is enough. And for related_name, instead of using area, we use content_object.
So, my resources.py should be,
class AreaResource(ModelResource):
tripl3user = fields.ManyToManyField(
'tripl3sales.api.resources.area.Tripl3UserResource',
'tripl3user',
related_name='content_object',
full=True
)
class Tripl3UserResource(ModelResource):
content_object = GenericForeignKeyField({
Area : AreaResource
}, 'content_object')
Hope this will help others.
Related
I am trying to access the Item model through the Thing queryset, and keep getting the error:
django.core.exceptions.FieldError: Field 'content_object' does not generate an automatic reverse relation and therefore cannot be used for reverse querying. If it is a GenericForeignKey, consider adding a GenericRelation.
class ThingContent(models.Model):
content_id = models.AutoField(primary_key=True, null=False)
thing = models.ForeignKey('Thing', on_delete=models.SET_NULL, null=True)
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey('content_type', 'object_id')
I have tried updating the fields on Item by adding a related_query_name to no success.
self.queryset.filter(items__item_date=exact_item_date))
class Item(models.Model):
id = models.AutoField(primary_key=True, null=False)
item_date = models.DateField(**options)
thing_content = GenericRelation('ThingContent', related_query_name='items')
content_object is generic. You must filter by object_id and content_type for know what object you FK generic.
You try again with query like this:
ThingContent.objects.filter(
items__item_date=item_date,
content_type=ContentType.objects.get_for_model(Item)
)
this query mean: find all ThingContent have mapping with Item, and have item_date like what you want filter.
How do I setup a model for a follow relationship, where a user can follow another user or a tag.
eg: userA is following (userB, userC, tag-Health, tag-Finance).
This was how I thought:
class Relationship(models.Model):
user = AutoOneToOneField(User)
content_type = models.ManyToManyField(ContentType, related_name='followed_by')
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey('content_type', 'object_id')
class Tag(models.Model):
name = models.CharField(max_length=10, unique=True)
But since ContentType only works for ForeignKey, how do I create a model so that a user can follow any of the two model (i.e. users and tags?
I have the following model in a Django app:
How can I get the "name" attribute of any selected content_object in this model and display it in list_display of the modelAdmin class, instead of just displaying the keys of the GenericForeign Key objects. Please I really need help with this.
class Checkout(models.Model):
checkout_date = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
check_in_complete = models.BooleanField(default=False, editable=False)
content_type = models.ForeignKey(ContentType,
limit_choices_to={"model__in": ('Facilitator', 'Enumerator', 'Tutor')})
object_id = models.PositiveIntegerField(verbose_name='Receiver')
content_object = GenericForeignKey('content_type', 'object_id')
Since GenericForeignKey is not a normal field object, you can not use it in filters:
Checkout.objects.filter(content_object=other_obj) # this will fail
But if you want to access the name property of the object your checkout is associated with using GenericForeignKey you can do it like following:
name = checkout_obj.content_object.name
I have the following models:
Class A(models.Model):
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
content_object = generic.GenericForeignKey('content_type', 'object_id')
thumbnail = models.ImageField(...)
class B(models.Model)
title = models.CharField()
def save(*args, **kwargs):
# Based on the title field I want to fetch some picture and then save the thumbnail in A
I have more classes like B which should be referenced from A (this is why I use GenericForeignKey). The problem I am trying to figure out is how to save the thumbnail field (on A) when I am in the save() method in B. Inserting many if statement in A to check the type of the referenced class and save the thumbnail accordingly is pretty cumbersome.
Looking at the docs, you can add a reverse generic relation from B to A:
If you know which models you’ll be using most often, you can also add a “reverse” generic relationship to enable an additional API
class A_Model(models.Model):
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
content_object = generic.GenericForeignKey('content_type', 'object_id')
thumbnail = models.ImageField(...)
class B_Models(models.Model)
title = models.CharField()
a_models = generic.GenericRelation(A_Model)
and now you can do:
b = B_Model()
a = A_Model(content_object=b, thumbnail=...)
a.save()
b.a_models.all()
I want the a counterpart of Tag (BlogPost) to have at least 1 instance of Tag or it shouldn't be created. (same effect like null=False). I tried a lot but couldn't figure out to apply these contrains. Any ideas?
class Tag(models.Model):
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
content_object = generic.GenericForeignKey('content_type', 'object_id')
text = models.CharField("text", max_length=255)
class Meta:
unique_together = ('content_type', 'object_id', 'text',)
class BlogPost(models.Model):
title = models.CharField("title", max_length=255)
tags = generic.GenericRelation(Tag, verbose_name="tags")
class TagInline(generic.GenericTabularInline):
model = Tag
extra = 1
class BlogPostAdmin(admin.ModelAdmin):
inlines = (TagInline,)
If you want this in the form of a Database constraint, then I'm not sure that such a thing exists.
Otherwise I would go with overriding the clean( self ) function on your model.
This can be used for custom validation.
def clean( self ):
# validate that this model has one or more tag