Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6249429
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 24, 20262026-05-24T13:14:13+00:00 2026-05-24T13:14:13+00:00

I have written the following custom field: from django.core.urlresolvers import reverse from django.db import

  • 0

I have written the following custom field:

from django.core.urlresolvers import reverse
from django.db import models
from django.db.models import signals
from sitetree.models import Tree, TreeItem
from south.modelsinspector import introspector

class AutoTreeItemField(models.ForeignKey):
    def __init__(self, *args, **kwargs):
        super(AutoTreeItemField, self).__init__(TreeItem, null=True)

        self.date_field = kwargs['date_field']
        self.__should_appear = kwargs['should_appear']
        self.year_menu_item_url = kwargs['year_menu_item_url']
        self.month_menu_item_url = kwargs['month_menu_item_url']
        self.item_menu_item_url = kwargs['item_menu_item_url']

        self.year_format = kwargs.get('year_format', '%Y')
        self.month_format = kwargs.get('month_format', '%B')
        self.inmenu = kwargs.get('inmenu', True)
        self.inbreadcrumbs = kwargs.get('inbreadcrumbs', True)
        self.insitetree = kwargs.get('insitetree', True)
        self.item_title = kwargs.get('title', 'title')

    def contribute_to_class(self, cls, name):
        super(AutoTreeItemField, self).contribute_to_class(cls, name)

        # Make this object the descriptor for field access.
        setattr(cls, self.name, self)

        self.tree = self.__get_or_create_tree(cls._meta.verbose_name_plural.lower())

        # Delete menu item after the instance is deleted
        signals.post_delete.connect(self.__delete, cls, True)

    def pre_save(self, model_instance, add):
        super(AutoTreeItemField, self).pre_save(model_instance, add)
        if self.should_appear(model_instance):
            year_menu_item = self.__get_or_create_year_tree_item(model_instance)
            month_menu_item = self.__get_or_create_month_tree_item(model_instance, year_menu_item)
            menu_item = self.__save_menu_item(model_instance, month_menu_item)
            setattr(model_instance, self.get_attname(), menu_item.id)

            return menu_item.id
        else:
            self.__delete_orphans(model_instance)

            return None

    def __delete(self, **kwargs):
        self.__delete_orphans(kwargs['instace'])

    def __get_or_create_tree(self, alias):
        try:
            return Tree.objects.get(alias=alias)
        except Tree.DoesNotExist:
            return Tree.objects.create(alias=alias)

    def should_appear(self, instance):
        if isinstance(self.__should_appear, str):
            return getattr(instance, self.__should_appear)
        elif callable(self.__should_appear):
            return self.__should_appear()

    def south_field_triple(self):
        """Returns a suitable description of this field for South."""
        args, kwargs = introspector(self)
        kwargs.update({'date_field': 'None'})
        return ('website.blog.fields.AutoTreeItemField', args, kwargs)

    def __get_or_create_year_tree_item(self, model_instance):
        year = self.__get_year(model_instance)

        try:
            return TreeItem.objects.get(title=year, tree=self.tree)
        except TreeItem.DoesNotExist:
            return TreeItem.objects.create(title=year,
                                           url=reverse(self.year_menu_item_url, args = [year]),
                                           tree=self.tree,
                                           inmenu=self.inmenu,
                                           inbreadcrumbs=self.inbreadcrumbs,
                                           insitetree=self.insitetree,
                                           parent=None)

    def __get_year(self, model_instance):
        return getattr(model_instance, self.date_field).strftime(self.year_format)

    def __get_or_create_month_tree_item(self, model_instance, year_menu_item):
        month = self.__get_month(model_instance)

        try:
            return TreeItem.objects.get(title=month, tree=self.tree, parent=year_menu_item)
        except TreeItem.DoesNotExist:
            return TreeItem.objects.create(title=month,
                                           url=reverse(self.month_menu_item_url, args = [getattr(model_instance, self.date_field).year, getattr(model_instance, self.date_field).month]),
                                           tree=self.tree,
                                           inmenu=self.inmenu,
                                           inbreadcrumbs=self.inbreadcrumbs,
                                           insitetree=self.insitetree,
                                           parent=year_menu_item)

    def __get_month(self, model_instance):
        return getattr(model_instance, self.date_field).strftime(self.month_format)

    def __save_menu_item(self, model_instance, month_tree_item):
        try:
            item = self.__get_menu_item(model_instance)

            item.title = getattr(model_instance, self.item_title)
            item.url = model_instance.get_absolute_url()
            item.parent = month_tree_item

            return item
        except TreeItem.DoesNotExist:
            return TreeItem.objects.create(title=getattr(model_instance, self.item_title),
                                           url=model_instance.get_absolute_url(),
                                           tree=self.tree,
                                           inmenu=self.inmenu,
                                           inbreadcrumbs=self.inbreadcrumbs,
                                           insitetree=self.insitetree,
                                           parent=month_tree_item)

    def __get_year_tree_item(self, model_instance):
        year = self.__get_year(model_instance)

        return TreeItem.objects.filter(title=year, tree=self.tree)

    def __delete_orphans(self, model_instance):
        menu_item = self.__get_menu_item(model_instance)

        try:
            if menu_item is not None:
                month_menu_item = menu_item.parent
                menu_item.delete()

                if TreeItem.objects.filter(parent=month_menu_item, parent__parent=self.__get_year_tree_item(model_instance), tree=self.tree).count():
                        year_menu_item = month_menu_item.parent

                        month_menu_item.delete()

                        if TreeItem.objects.filter(parent=year_menu_item, tree=self.tree).count() == 0:
                            year_menu_item.delete()
        except TreeItem.DoesNotExist:
            pass

    def __get_menu_item(self, model_instance):
        menu_item_id = getattr(model_instance, self.get_attname())
        return TreeItem.objects.get(id=menu_item_id)

But when I’m attempting to save it I am getting:

'AutoTreeItemField' object has no attribute '_meta'

Here’s the full stacktrace:

Environment:


Request Method: POST
Request URL: http://127.0.0.1:8000/admin/blog/draftpost/add/

Django Version: 1.3
Python Version: 2.7.1
Installed Applications:
['django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.sites',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'django.contrib.admin',
 'django.contrib.sites',
 'django.contrib.flatpages',
 'tagging',
 'reversion',
 'south',
 'sitetree',
 'dojango',
 'disqus',
 'website.blog',
 'website.cms']
Installed Middleware:
('django.middleware.common.CommonMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'dojango.middleware.DojoCollector',
 'django.contrib.flatpages.middleware.FlatpageFallbackMiddleware')


Traceback:
File "C:\Python27\lib\site-packages\django\core\handlers\base.py" in get_response
  111.                         response = callback(request, *callback_args, **callback_kwargs)
File "C:\Python27\lib\site-packages\django\contrib\admin\options.py" in wrapper
  307.                 return self.admin_site.admin_view(view)(*args, **kwargs)
File "C:\Python27\lib\site-packages\django\utils\decorators.py" in _wrapped_view
  93.                     response = view_func(request, *args, **kwargs)
File "C:\Python27\lib\site-packages\django\views\decorators\cache.py" in _wrapped_view_func
  79.         response = view_func(request, *args, **kwargs)
File "C:\Python27\lib\site-packages\django\contrib\admin\sites.py" in inner
  197.             return view(request, *args, **kwargs)
File "C:\Python27\lib\site-packages\django\db\transaction.py" in inner
  217.                 res = func(*args, **kwargs)
File "C:\Python27\lib\site-packages\reversion\revisions.py" in _create_on_success
  352.                 self.end()
File "C:\Python27\lib\site-packages\reversion\revisions.py" in end
  274.                     revision_set = self.follow_relationships(models)
File "C:\Python27\lib\site-packages\reversion\revisions.py" in follow_relationships
  244.         map(_follow_relationships, object_dict)
File "C:\Python27\lib\site-packages\reversion\revisions.py" in _follow_relationships
  243.                     _follow_relationships(parent_obj)
File "C:\Python27\lib\site-packages\reversion\revisions.py" in _follow_relationships
  213.             result_dict[obj] = self.get_version_data(obj, VERSION_CHANGE)
File "C:\Python27\lib\site-packages\reversion\revisions.py" in get_version_data
  254.         serialized_data = serializers.serialize(registration_info.format, [obj], fields=registration_info.fields)
File "C:\Python27\lib\site-packages\django\core\serializers\__init__.py" in serialize
  91.     s.serialize(queryset, **options)
File "C:\Python27\lib\site-packages\django\core\serializers\base.py" in serialize
  48.                             self.handle_fk_field(obj, field)
File "C:\Python27\lib\site-packages\django\core\serializers\python.py" in handle_fk_field
  53.                 if field.rel.field_name == related._meta.pk.name:

Exception Type: AttributeError at /admin/blog/draftpost/add/
Exception Value: 'AutoTreeItemField' object has no attribute '_meta'

Can anyone exlpain to me how can this be? What could be done to remedy this issue?
The wierd thing is that it happens after the transaction ends and it saves everything I need to the database.

EDIT:
The error is caused by reversion trying to serialize my instance into json. However, this is still my problem because the _meta attribute should have been there and it isn’t. How can this be resolved?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-24T13:14:14+00:00Added an answer on May 24, 2026 at 1:14 pm

    The first thing that comes to my mind is that in the following comment:

            # Make this object the descriptor for field access.
            setattr(cls, self.name, self)
    

    you state that your field instance should act as a descriptor, yet it does not implement __get__ nor __set__, which are required for the descriptor protocol. Note that ForeignKey itself also does not implement those, instead, it uses a ReverseSingleRelatedObjectDescriptor.

    Now, what happens in your case is that the serializer sees that the field is a ForeignKey, therefore it expects a model instance to be sitting in its name on the model instance. It calls getattr(obj, field.name) which would normally invoke the ReverseSingleRelatedObjectDescriptor‘s __get__ method and return an instance of the related model. In your case that particular getattr call returns your field instance (since it lacks __get__) instead of a TreeItem instance and that is when things go wrong.

    So, to help you with your problem, I’d choose a completely different approach. From your code it seems to me that all you need is a few convenient methods accessible from the instances containing your AutoTreeItemField that work automatically with a related TreeItem pointed to by a ForeignKey.

    I’d rather keep the field a regular ForeignKey and instead attach the convenience methods to your model class. If you need them in several models, you can always create a mixin and if you want it to be really neat, you can make a custom ForeignKey subclass that would only override its contribute_to_class to automatically add the mixin to cls.__bases__.

    If you need the ForeignKeys to be in different field names, you can even go as far as dynamically create the names of your methods by prepending them with your field’s name and currying them to supply the field name as a parameter. The possibilities are almost endless.

    EDIT: This can be done, for example, by creating a mixin class containing all your handy extra methods with names prefixed by _TREEITEM. You’ll also have to make them accept all your extra parameters, like year_format, month_format, inmenu etc. as keyword arguments. Save these in your ForeignKey subclass’ __init__ method as you do currently, then in its contribute_to_class do something like this:

    from django.utils.functional import curry
    
    ...
    
        def contribute_to_class(self, cls, name):
            super(...).contribute_to_class(cls, name)
            cls.__bases__ += (TreeItemMixin,)
            # Now curry all your handy methods to pass your extra parameters to them.
            extra_kwargs = {
                'year_format': self.year_format,
                # ...
            }
            setattr(cls, '%s_get_year' % (self.name,), curry(cls._TREEITEM_get_year, **extra_kwargs))
            # Repeat the previous line for all your methods.
    

    Also, in your ForeignKey subclass you can keep your pre_save and your signal handler, just remember to call the appropriate methods on your model instance. When you want to call them from within your views or your business logic, you have the handy curried auto-generated aliases available on your model instances, like obj.myfield_get_year().

    The other possibility is to implement the descriptor protocol in your AutoTreeItemField to return valid TreeItem instances but in that case you won’t be able to access its extra methods since the descriptor will return model instances instead of itself.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I am have written the following code below to encode a bitarray into custom
I have written a Custom Control that contains the following: [assembly: System.Web.UI.WebResource(InSysControls.AssignmentLists.AssignmentLists.js, text/javascript)] namespace
I have written the following macro, that defines records with a custom string representation.
I have written following code to attach gesture recogniser to multiple imageviews. [imageview1 setUserInteractionEnabled:YES];
I am trying my hands on WPF MVVM. I have written following code in
i have written the following code class Program { static void Main(string[] args) {
I have written the following code, CrystalDecisions.CrystalReports.Engine.ReportDocument report = new CrystalDecisions.CrystalReports.Engine.ReportDocument(); report.Load(@C:\Users\XXX\Desktop\Backup1\Project\ReportsFolder\ReportSalesInvoice.rpt); Report works
I have written the following algorithm in order to evaluate a function in MatLab
I have written the following query, but in the WHERE clause I have used
I have written the following constraint for a column I've called 'grade': CONSTRAINT gradeRule

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.