0

The problem is, I have to give foreign key reference to two different models so as to record the activity logs of the user

I have model named Activity Log to record the activities done by the user

class ActivityLog(models.Model):
    target = models.ForeignKey(Build, on_delete=models.CASCADE, null=True, blank=True)
    # Target, (Optional) The object to which the activity was performed.
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    # Actor  The object that performed the activity.
    action_object = models.ForeignKey(Team, on_delete=models.CASCADE, null=True, blank=True)
    # Action Object. (Optional) The object linked to the action itself.
    content = models.TextField()
    # Content of the activity
    timestamp = models.DateTimeField()

I need to give the target field with foreign key refering to two different models. Is it possible to use generic relations?

ams_py
  • 41
  • 2
  • 6
  • Welcome to stackoverflow, your question is similar to [this one](https://stackoverflow.com/questions/33528098/django-model-one-foreign-key-to-many-tables) check it out and if you still had any questions, please ask. – Sajad Mar 30 '20 at 09:58
  • Does this answer your question? [Django - using multiple foreign key to the same model](https://stackoverflow.com/questions/41697771/django-using-multiple-foreign-key-to-the-same-model) – victor dencowski Mar 30 '20 at 15:07

1 Answers1

0

Yes, use generic relations

from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType
from django.db import models

class ActivityLog(models.Model):
    target_type = models.ForeignKey(ContentType)
    target_id = models.Charfield(max_length=50)
    target = GenericForeignKey('target_type', 'target_id')
    ...
    content = models.TextField()

# Usage   
target1 = Foo.objects.get(...)
target2 = Bar.objects.get(...)

ActivityLog(target=target1, content="Did something to foo").save()
ActivityLog(target=target2, content="Did something to bar").save()
Victor
  • 2,864
  • 1
  • 12
  • 20
  • Thanks, I have tried this and also I have some existing data along with this. When I tried to update it with scripts "ValueError: Cannot assign "": "ActivityLog.target_type" must be a "ContentType" instance." I tried by updating the target_type and target_id. – ams_py Mar 31 '20 at 08:14
  • You can manually change the target_type and target_id, but the target field is there so you don't have to do so. You can just pass any instance of any model to the GenericForeignKey field – Victor Mar 31 '20 at 10:25
  • While retrieving the data, Is there any special procedure that we have to look for? – ams_py Mar 31 '20 at 10:52
  • Unfortunately, for retrieving data, then that's when you have to manually specify the target_type and target_id in queries. https://docs.djangoproject.com/en/3.0/ref/contrib/contenttypes/ – Victor Mar 31 '20 at 11:11
  • Thanks for the help, will try it out. – ams_py Apr 01 '20 at 05:48
  • Is there any possible ways to compare the models from target_type? i,e how can we identify the models? (while retrieving the data) – ams_py Apr 01 '20 at 11:39