1717from xadmin .plugins .actions import BaseActionView
1818from xadmin .plugins .inline import InlineModelAdmin
1919from xadmin .sites import site
20- from xadmin .util import unquote , quote , model_format_dict ,is_related_field
20+ from xadmin .util import unquote , quote , model_format_dict , is_related_field2
2121from xadmin .views import BaseAdminPlugin , ModelAdminView , CreateAdminView , UpdateAdminView , DetailAdminView , ModelFormAdminView , DeleteAdminView , ListAdminView
2222from xadmin .views .base import csrf_protect_m , filter_hook
2323from xadmin .views .detail import DetailAdminUtil
2424from reversion .models import Revision , Version
25- from reversion .revisions import default_revision_manager , RegistrationError
25+ from reversion .revisions import is_active , register , is_registered , set_comment , create_revision , set_user
26+ from contextlib import contextmanager
2627from functools import partial
2728
2829
2930def _autoregister (admin , model , follow = None ):
3031 """Registers a model with reversion, if required."""
3132 if model ._meta .proxy :
3233 raise RegistrationError ("Proxy models cannot be used with django-reversion, register the parent class instead" )
33- if not admin . revision_manager . is_registered (model ):
34+ if not is_registered (model ):
3435 follow = follow or []
3536 for parent_cls , field in model ._meta .parents .items ():
3637 follow .append (field .name )
3738 _autoregister (admin , parent_cls )
38- admin .revision_manager .register (
39- model , follow = follow , format = admin .reversion_format )
39+ register (model , follow = follow , format = admin .reversion_format )
4040
4141
4242def _register_model (admin , model ):
43- if not hasattr (admin , 'revision_manager' ):
44- admin .revision_manager = default_revision_manager
4543 if not hasattr (admin , 'reversion_format' ):
4644 admin .reversion_format = 'json'
4745
48- if not admin . revision_manager . is_registered (model ):
46+ if not is_registered (model ):
4947 inline_fields = []
5048 for inline in getattr (admin , 'inlines' , []):
5149 inline_model = inline .model
@@ -80,12 +78,14 @@ def register_models(admin_site=None):
8078 if getattr (admin , 'reversion_enable' , False ):
8179 _register_model (admin , model )
8280
81+ @contextmanager
82+ def do_create_revision (request ):
83+ with create_revision ():
84+ set_user (request .user )
85+ yield
8386
8487class ReversionPlugin (BaseAdminPlugin ):
8588
86- # The revision manager instance used to manage revisions.
87- revision_manager = default_revision_manager
88-
8989 # The serialization format to use when registering models with reversion.
9090 reversion_format = "json"
9191
@@ -97,32 +97,6 @@ class ReversionPlugin(BaseAdminPlugin):
9797 def init_request (self , * args , ** kwargs ):
9898 return self .reversion_enable
9999
100- @property
101- def revision_context_manager (self ):
102- """The revision context manager for this VersionAdmin."""
103- return self .revision_manager ._revision_context_manager
104-
105- def get_revision_instances (self , obj ):
106- """Returns all the instances to be used in the object's revision."""
107- return [obj ]
108-
109- def get_revision_data (self , obj , flag ):
110- """Returns all the revision data to be used in the object's revision."""
111- return dict (
112- (o , self .revision_manager .get_adapter (
113- o .__class__ ).get_version_data (o , flag ))
114- for o in self .get_revision_instances (obj )
115- )
116-
117- def save_revision (self , obj , tag , comment ):
118- self .revision_manager .save_revision (
119- self .get_revision_data (obj , tag ),
120- user = self .user ,
121- comment = comment ,
122- ignore_duplicates = self .ignore_duplicate_revisions ,
123- db = self .revision_context_manager .get_db (),
124- )
125-
126100 def do_post (self , __ ):
127101 def _method ():
128102 self .revision_context_manager .set_user (self .user )
@@ -144,23 +118,8 @@ def _method():
144118 return _method
145119
146120 def post (self , __ , request , * args , ** kwargs ):
147- return self .revision_context_manager .create_revision (manage_manually = False )(self .do_post (__ ))()
148-
149- # def save_models(self, __):
150- # self.revision_context_manager.create_revision(manage_manually=True)(__)()
151-
152- # if self.admin_view.org_obj is None:
153- # self.save_revision(self.admin_view.new_obj, VERSION_ADD, _(u"Initial version."))
154- # else:
155- # self.save_revision(self.admin_view.new_obj, VERSION_CHANGE, _(u"Change version."))
156-
157- # def save_related(self, __):
158- # self.revision_context_manager.create_revision(manage_manually=True)(__)()
159-
160- # def delete_model(self, __):
161- # self.save_revision(self.admin_view.obj, VERSION_DELETE, \
162- # _(u"Deleted %(verbose_name)s.") % {"verbose_name": self.opts.verbose_name})
163- # self.revision_context_manager.create_revision(manage_manually=True)(__)()
121+ with do_create_revision (request ):
122+ return __ ()
164123
165124 # Block Views
166125 def block_top_toolbar (self , context , nodes ):
@@ -173,21 +132,30 @@ def block_nav_toggles(self, context, nodes):
173132 if obj :
174133 revisionlist_url = self .admin_view .model_admin_url (
175134 'revisionlist' , quote (obj .pk ))
176- nodes .append (mark_safe ('<a href="proxy.php?url=https%3A%2F%2Fgithub.com%2F%25s" class="navbar-toggle pull-right"><i class="fa fa-time "></i></a>' % revisionlist_url ))
135+ nodes .append (mark_safe ('<a href="proxy.php?url=https%3A%2F%2Fgithub.com%2F%25s" class="navbar-toggle pull-right"><i class="fa fa-calendar "></i></a>' % revisionlist_url ))
177136
178137 def block_nav_btns (self , context , nodes ):
179138 obj = getattr (
180139 self .admin_view , 'org_obj' , getattr (self .admin_view , 'obj' , None ))
181140 if obj :
182141 revisionlist_url = self .admin_view .model_admin_url (
183142 'revisionlist' , quote (obj .pk ))
184- nodes .append (mark_safe ('<a href="proxy.php?url=https%3A%2F%2Fgithub.com%2F%25s" class="btn btn-default"><i class="fa fa-time "></i> <span>%s</span></a>' % (revisionlist_url , _ (u'History' ))))
143+ nodes .append (mark_safe ('<a href="proxy.php?url=https%3A%2F%2Fgithub.com%2F%25s" class="btn btn-default"><i class="fa fa-calendar "></i> <span>%s</span></a>' % (revisionlist_url , _ (u'History' ))))
185144
145+ # action revision
146+ class ActionRevisionPlugin (BaseAdminPlugin ):
186147
187- class BaseReversionView (ModelAdminView ):
148+ reversion_enable = False
149+
150+ def init_request (self , * args , ** kwargs ):
151+ return self .reversion_enable
152+
153+ def do_action (self , __ , queryset ):
154+ with do_create_revision (self .request ):
155+ return __ ()
188156
189- # The revision manager instance used to manage revisions.
190- revision_manager = default_revision_manager
157+
158+ class BaseReversionView ( ModelAdminView ):
191159
192160 # The serialization format to use when registering models with reversion.
193161 reversion_format = "json"
@@ -218,8 +186,7 @@ class RecoverListView(BaseReversionView):
218186 def get_context (self ):
219187 context = super (RecoverListView , self ).get_context ()
220188 opts = self .opts
221- deleted = self ._order_version_queryset (
222- self .revision_manager .get_deleted (self .model ))
189+ deleted = self ._order_version_queryset (Version .objects .get_deleted (self .model ))
223190 context .update ({
224191 "opts" : opts ,
225192 "app_label" : opts .app_label ,
@@ -245,6 +212,12 @@ class RevisionListView(BaseReversionView):
245212 object_history_template = None
246213 revision_diff_template = None
247214
215+ def _reversion_order_version_queryset (self , queryset ):
216+ """Applies the correct ordering to the given version queryset."""
217+ if not self .history_latest_first :
218+ queryset = queryset .order_by ("pk" )
219+ return queryset
220+
248221 def get_context (self ):
249222 context = super (RevisionListView , self ).get_context ()
250223
@@ -256,7 +229,7 @@ def get_context(self):
256229 "version" : version
257230 }
258231 for version
259- in self ._order_version_queryset ( self . revision_manager .get_for_object_reference (
232+ in self ._reversion_order_version_queryset ( Version . objects .get_for_object_reference (
260233 self .model ,
261234 self .obj .pk ,
262235 ).select_related ("revision__user" ))
@@ -289,7 +262,7 @@ def get_response(self):
289262 self .get_template_list ('views/model_history.html' ), context , current_app = self .admin_site .name )
290263
291264 def get_version_object (self , version ):
292- obj_version = version .object_version
265+ obj_version = version ._object_version
293266 obj = obj_version .object
294267 obj ._state .db = self .obj ._state .db
295268
@@ -332,7 +305,7 @@ def post(self, request, object_id, *args, **kwargs):
332305 obj_b , detail_b = self .get_version_object (version_b )
333306
334307 for f in (self .opts .fields + self .opts .many_to_many ):
335- if is_related_field (f ):
308+ if is_related_field2 (f ):
336309 label = f .opts .verbose_name
337310 else :
338311 label = f .verbose_name
@@ -407,7 +380,7 @@ def render(self, form, form_style, context, template_pack=TEMPLATE_PACK, **kwarg
407380 html = ''
408381 for field in self .fields :
409382 html += ('<div class="diff_field" rel="tooltip"><textarea class="org-data" style="display:none;">%s</textarea>%s</div>' %
410- (_ ('Current: %s' ) % self .attrs .pop ('orgdata' , '' ), render_field (field , form , form_style , context , template = self . template , attrs = self .attrs )))
383+ (_ ('Current: %s' ) % self .attrs .pop ('orgdata' , '' ), render_field (field , form , form_style , context , template_pack = template_pack , attrs = self .attrs )))
411384 return html
412385
413386
@@ -428,8 +401,17 @@ def get_form_helper(self):
428401 helper = super (RevisionView , self ).get_form_helper ()
429402 diff_fields = {}
430403 version_data = self .version .field_dict
404+ print version_data
431405 for f in self .opts .fields :
432- if f .value_from_object (self .org_obj ) != version_data .get (f .name , None ):
406+ fvalue = f .value_from_object (self .org_obj )
407+ vvalue = version_data .get (f .name , None )
408+
409+ if fvalue is None and vvalue == '' :
410+ vvalue = None
411+ if is_related_field2 (f ):
412+ vvalue = version_data .get (f .name + '_' + f .rel .get_related_field ().name , None )
413+
414+ if fvalue != vvalue :
433415 diff_fields [f .name ] = self .detail .get_field_result (f .name ).val
434416 for k , v in diff_fields .items ():
435417 helper [k ].wrap (DiffField , orgdata = v )
@@ -469,7 +451,7 @@ def init_request(self, version_id):
469451 raise PermissionDenied
470452
471453 self .version = get_object_or_404 (Version , pk = version_id )
472- self .org_obj = self .version .object_version .object
454+ self .org_obj = self .version ._object_version .object
473455
474456 self .prepare_form ()
475457
@@ -511,7 +493,7 @@ def render(self, form, form_style, context, template_pack=TEMPLATE_PACK, **kwarg
511493 for field in self .fields :
512494 f = opts .get_field (field )
513495 f_html = render_field (field , form , form_style , context ,
514- template = self . template , attrs = self .attrs )
496+ template_pack = template_pack , attrs = self .attrs )
515497 if f .value_from_object (instance ) != initial .get (field , None ):
516498 current_val = detail .get_field_result (f .name ).val
517499 html += ('<div class="diff_field" rel="tooltip"><textarea class="org-data" style="display:none;">%s</textarea>%s</div>'
@@ -530,7 +512,7 @@ def get_related_versions(self, obj, version, formset):
530512 object_id = obj .pk
531513 # Get the fk name.
532514 try :
533- fk_name = formset .fk .name
515+ fk_name = formset .fk .name + '_' + formset . fk . rel . get_related_field (). name
534516 except AttributeError :
535517 # This is a GenericInlineFormset, or similar.
536518 fk_name = formset .ct_fk_field .name
@@ -595,34 +577,6 @@ def instance_form(self, formset, **kwargs):
595577 self ._hack_inline_formset_initial (admin_view , formset )
596578 return formset
597579
598- # action revision
599-
600-
601- class ActionRevisionPlugin (BaseAdminPlugin ):
602-
603- revision_manager = default_revision_manager
604- reversion_enable = False
605-
606- def init_request (self , * args , ** kwargs ):
607- return self .reversion_enable
608-
609- @property
610- def revision_context_manager (self ):
611- return self .revision_manager ._revision_context_manager
612-
613- def do_action_func (self , __ ):
614- def _method ():
615- self .revision_context_manager .set_user (self .user )
616- action_view = self .admin_view
617- comment = action_view .description % model_format_dict (self .opts )
618-
619- self .revision_context_manager .set_comment (comment )
620- return __ ()
621- return _method
622-
623- def do_action (self , __ , queryset ):
624- return self .revision_context_manager .create_revision (manage_manually = False )(self .do_action_func (__ ))()
625-
626580
627581class VersionInline (object ):
628582 model = Version
0 commit comments