I have the below code written in django
from django.db import models
from django.contrib.auth.models import User
class AuditColumns(models.Model):
created_at=models.DateField("Created at")
created_by=models.ForeignKey(User, db_column="created_by", related_name="poll_user_created_by")
updated_at=models.DateTimeField("Updated at")
updated_by=models.ForeignKey(User, db_column="updated_by", null=True, related_name="poll_user_updated_by")
class Meta:
abstract = True
class Poll(AuditColumns):
question=models.CharField(max_length=300)
start_poll_at=models.DateTimeField(null=True)
end_poll_at=models.DateTimeField(null=True)
is_active=models.BooleanField(default=True)
class Choice(AuditColumns):
choice=models.CharField(max_length=200)
when i execute this code am getting the following error
mo@debian:~/PycharmProjects/KlamTam$ ./manage.py sql polls
Error: One or more models did not validate:
polls.poll: Accessor for field 'created_by' clashes with related field 'User.poll_user_created_by'. Add a related_name argument to the definition for 'created_by'.
polls.poll: Reverse query name for field 'created_by' clashes with related field 'User.poll_user_created_by'. Add a related_name argument to the definition for 'created_by'.
polls.poll: Accessor for field 'updated_by' clashes with related field 'User.poll_user_updated_by'. Add a related_name argument to the definition for 'updated_by'.
polls.poll: Reverse query name for field 'updated_by' clashes with related field 'User.poll_user_updated_by'. Add a related_name argument to the definition for 'updated_by'.
polls.choice: Accessor for field 'created_by' clashes with related field 'User.poll_user_created_by'. Add a related_name argument to the definition for 'created_by'.
polls.choice: Reverse query name for field 'created_by' clashes with related field 'User.poll_user_created_by'. Add a related_name argument to the definition for 'created_by'.
polls.choice: Accessor for field 'updated_by' clashes with related field 'User.poll_user_updated_by'. Add a related_name argument to the definition for 'updated_by'.
polls.choice: Reverse query name for field 'updated_by' clashes with related field 'User.poll_user_updated_by'. Add a related_name argument to the definition for 'updated_by'.
this has to do with setting up a unique related_name, is there a way to dynamically generate related_names to make sure they always unique? off course it would be better to know what is related_name for and if possible to avoid setting them?
Regards,
Related names are provided by the Django ORM to enable you to easily find all models that key into the current model. So if you have a key from a Foo to a Bar, the instance of Bar will have, by default, an attribute called foo_set that would give you a list of all Foos that are linked to that specific Bar.
You can specify your own related_name to make your code easier to read back, with more natural/appropriate related_names.
However, as you're seeing, Django's ORM requires unique related_name values, and because you've got FKs in your base class, it's automatically creating those FKs for all child models and using the same name for them, which - clearly - is not viable.
Good news is, this note in the documentation shows a workaround for Django 1.2+
If, for some reason, you're having to use Django 1.1 or earlier, here's an alternative workaround: Instead of using FKs on the abstract model, just use a field to store the pk for the keyed model, and add accessors accordingly. eg:
class AuditBase(models.Model):
created_at = models.DateTimeField("Created at", auto_now_add=True)
created_by = models.IntegerField(required=True)
updated_at = models.DateTimeField("Updated at", auto_now=True)
updated_by = models.IntegerField(required=True)
class Meta:
abstract = True
@property
def creator(self):
return User.objects.get(id=self.created_by)
@property
def last_editor(self):
return User.objects.get(id=self.updated_by)
def save(self, *args, **kwargs):
#track the creator/last editor via an optional kwarg
active_user = self.kwargs.get('user')
if active_user:
self.updated_by = active_user
if active_user and not self.created_by:
self.created_by = active_user
return super(AuditBase, self).save(*args, **kwargs)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With