How to restore Models original Properties - Problem in Models column Exclude

15 views
Skip to first unread message

Balaji Shetty

unread,
May 27, 2019, 3:21:48 PM5/27/19
to django...@googlegroups.com
Hi
i have encountered very strange problem.  have two user . One is superuser of name "root" and another is general user of name "dgp". I have model of Name Profile with 21 fields around.

I want to show all field of Model Profile in "root" login.
I want to exclude 4 field of Model Profile in "dgp" login.

I get correct output If i do login in this sequence root - dgp
I get wrong output If i do login in this sequence  dgp - root
( Means I get 4 field excluded in root Login also. )
Means once i do login using "dgp" user , i always get all 4 fields excluded in subsequent login for any user unless and until i restart the server.

I have a model of name Profile and I want to exclude four fields for user of name  "dgp" .

Fields are
 username = request.user.username
    if username == "dgp":
       self.exclude = ('UserNext','UserNextDate','UserNextDepartment','CaseStatus', )

I have superuser as root.
1.  When I run the code and do the login using root user login
I get all Fields of Profile Model.
2 I do logout and Login Using "dgp" user. I get all Fields of Profile Model except
the four fields.      'UserNext','UserNextDate','UserNextDepartment','CaseStatus', )

Here My code Execute successfully.

But when I change the sequence of Login, Code shows the
all Fields of Profile Model except
the four fields in both login "dgp" as well as "root".

I have overridden Models Two methods. Necessary Model and admin code is shown below.

Please help n this regards.
     


models.py

-------------------------------

class Profile(models.Model):

    RCS1 = "Regular_Civil_Suit"
    SCS1 = "Special_Civil_Suit"
    RCA1 = "Regular Civil Appeal"
    MCA1 = "Miscellaneous Civil Appeal"
    CMA1 = "Civil Miscellaneous Application"
    LAR1 = "Land Acquisation Reference"
    SED1 = "Special Execution Darkhast"
    # AC1 = "Arbitration Case"

    SuitType_Choice = [
           (RCS1, 'Regular Civil Suit'),
           (SCS1, 'Special Civil Suit'),
           (RCA1, 'Regular Civil Appeal'),
           (MCA1,'Miscellaneous Civil Appeal'),
           (CMA1,'Civil Miscellaneous Application'),
           (LAR1,'Land Acquisation Reference'),
           (SED1,'Special Execution Darkhast'),
           # (AC1,’Arbitration Case’),
      ]

    State = models.CharField(max_length=100,default="MH")
    District = models.CharField(max_length=100,default="Parbhani")
   
    user = models.ForeignKey(User, on_delete=models.CASCADE,default="--")
    InwardNumber = models.CharField(max_length=100,default="2019/3")
    CaseNoticeDate = models.DateField(default="2019-01-24")
    CaseNoticeSubject = models.CharField(max_length=100,default="Inquiry in Department")
    CaseReceiverName = models.CharField(max_length=100,default="Ramakant Lal")
    CaseInwardDate = models.DateField(default="2019-02-24")
    CaseActionTaken=models.CharField(max_length=200,default="Verification is going on")
 
    CourtType =models.CharField(max_length=200,default="District Court Parbhani")
    SuitType= models.CharField(max_length=200,choices=SuitType_Choice,
        default="Regular Civil Suit",verbose_name='--Suit Type-')
     # decision_taken = models.CharField(max_length=50, choices=court_action,
     #   default="Appeared",verbose_name='Court Decision-')
 
    CaseYear = models.PositiveIntegerField(default=2019)
    CaseNumber = models.PositiveIntegerField(default=1)
    CaseSubmittedDate = models.DateField(default="2019-01-14")
    # Current_Date= models.DateField(default=timezone.now)
    CaseSubject=models.CharField(max_length=200,default="Corruption and Dowry")
 
    CaseAdvocate=models.CharField(max_length=200,default="Reguar Civil Suit")
    CasePartyNames=models.CharField(max_length=200,default="Manish Singh")
    CaseOppositePartyNames=models.CharField(max_length=200,default="Raj Kumar ")
    CaseLastDate = models.DateField(default="2019-05-24")
 
    UserCurrent =  models.CharField(max_length=200,default="user1")
    UserCurrentDate = models.DateField(default="2019-03-24")
    UserCurrentDepartment =  models.CharField(max_length=200,default="IT")
   
    UserNext =  models.CharField(max_length=200,default="user2")
    UserNextDate = models.DateField(default="2019-06-24")
    UserNextDepartment =  models.CharField(max_length=200,default="CS")
   
    CaseStatus= models.CharField(max_length=100,default="Pending")


    # CaseNumber = models.PositiveIntegerField(default=1)
    # CaseYear = models.PositiveIntegerField(default=2019)
   
    class Meta:
        unique_together = (('CaseNumber', 'CaseYear'),)
 
   
    def __str__(self):
        return '%s/%s' % (self.CaseNumber, self.CaseYear)
-----------------------------------------------------------------------




admin.py
+++++++++++++++++++++++++++++++++++++++++++
  def add_view(self, request, extra_context=None):
    username = request.user.username
   
    print("----- Inside ADD VIEW Method--------")
    print (username)

    self._request = request        


    if username == "dgp":
      print("----- Inside ADD VIEW DGP Condition--------")  
      self.exclude = ('UserNext','UserNextDate','UserNextDepartment','CaseStatus', )    
    else:
         print("----- Inside ADD VIEW  ***NON DGP*** Condition--------")  

    # return super().add_view(request, extra_context)
    return super().changeform_view(request, extra_context)

   
  def change_view(self, request, object_id,  extra_context=None):
        # extra_context = extra_context or {}
        # extra_context['osm_data'] = self.get_osm_info()
    username = request.user.username
   
    print("Inside CHANGE VIEW Method--------")
    print (username)

    if username == "dgp":
       self.exclude = ('UserNext','UserNextDate','UserNextDepartment','CaseStatus', )
       print("----- Inside CHANGE VIEW  IN  DGP User Condition--------")  
    else:
       print("----- Inside CHANGE VIEW **** other THAN DG**P User Condition--------")  
   

       # self.include = ('UserNext','UserNextDate','UserNextDepartment','CaseStatus', )    
     
    return super().change_view(
            request, object_id, extra_context=extra_context,
    )



--
Mr. Shetty Balaji S.
Asst. Professor
Department of Information Technology,
SGGS Institute of Engineering & Technology, Vishnupuri, Nanded.MH.India
  Mobile: +91-9270696267

Alexis Roda

unread,
May 27, 2019, 4:25:42 PM5/27/19
to django...@googlegroups.com
Not an admin expert here.

You are modifying the modeladmin instance and, by the behavior you're describing, it looks like it is a global (shared) object. I'm guessing, you can confirm this by printing id(self) in add_view(). I'll bet you get the same value in each request, so the instance is shared, so the change is visible (persisted) across request boundaries.

You may think about adding self.exclude = () in the else branch in order to not exclude anything. Don't do that, you may end up leaking private information to dgp if both root and dgp are logged in at the same time.

Instead override the get_exclude method.


Balaji Shetty

unread,
May 28, 2019, 3:33:20 AM5/28/19
to django...@googlegroups.com
Dear  Alexis Roda Sir

Thank You very much for your nice reply. I check it.

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users...@googlegroups.com.
To post to this group, send email to django...@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/CAMDYoXbb42hpu3jAATXTwxPw9kO8XeZpLOczbNa-Bzw5QAdGuQ%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Balaji Shetty

unread,
May 28, 2019, 10:22:08 AM5/28/19
to django...@googlegroups.com
This is the proper code to customize models column userwise.
Here we are sharing model among multiple user and depending upon right access, it is visible

in admin.py

  normaluser_fields = ['user','CourtType','SuitType','CaseNumber','CaseYear','CaseAdvocate','CasePartyNames',
                    'CaseOppositePartyNames','CaseLastDate']
  superuser_fields = ['UserNext','UserNextDate','UserNextDepartment','CaseStatus']
  inward_fields = ['InwardNumber','CaseNoticeDate','CaseNoticeSubject','CaseReceiverName','CaseInwardDate','CaseActionTaken']


  def get_form(self, request, obj=None, **kwargs):

        username = request.user.username
   
        print("----- Inside get_exclude Method--------")
        print (username)

        if username == 'dgp': # if user is not a superuser
       
        # if request.user.is_superuser:
            # print("-----  ***********  Inside ROOT LOGIN ***-------")

            self.fields = self.normaluser_fields
        elif username == 'inumber':
            print("-----  ***********  Inside DGP LOGIN ***-------")
            self.fields = self.inward_fields
        else:
            self.fields = self.normaluser_fields + self.superuser_fields + self.inward_fields
                 

        return super(ProfileAdmin, self).get_form(request, obj, **kwargs)


Alexis Roda

unread,
May 28, 2019, 11:04:37 AM5/28/19
to django...@googlegroups.com
No, it isn't. It's not thread safe.

Changes in shared state in multi-threaded code may lead to race conditions[1].

Depending on your usage it may be very unlikely, but under the right circumstances root may end up having some missing fields in the form or dgp may see fields that it is not intended to see.

Either protect the critical section[2] with some kind of lock or, as I suggested in my previous answer, create non-shared (request local) state.



Balaji Shetty

unread,
May 31, 2019, 10:43:01 AM5/31/19
to django...@googlegroups.com
Dear Alexis Roda Sir

Thank You very Much.

definitely Race Condition may arise if we do not put code inn critical section. But your suggested approach did not work and i found another alternative which is working fine. If we put this code with necessary care than will it be ok?



--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users...@googlegroups.com.
To post to this group, send email to django...@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.

For more options, visit https://groups.google.com/d/optout.

Alexis Roda

unread,
May 31, 2019, 3:25:02 PM5/31/19
to django...@googlegroups.com
Hi Balaji,

Sorry but I don't understand what do you mean with "If we put this code with necessary care".

All I can say is that your code is not thread safe and it may break. How likely is this to happen depends on the usage patterns of your app. How serious it will be depends on the leaked data. Depending on context/constraints it might be a perfectly good enough solution. It's up to you deciding if it's worth fixing it.

That being said, overriding get_exclude works for me: it hides/shows some fields in an admin form depending on some condition (and it's thread safe). It requires django 1.11 or newer and it may be affected by fields and readonly_fields defined in the model admin and in the model form. Please, provide the relevant code, errors etc. if you require further assistance with this.

Another approach would be overriding get_form as shown in the django docs[1].

The point is that neither of those solutions makes changes to shared state (the admin).


HTH


Missatge de Balaji Shetty <balaji...@gmail.com> del dia dv., 31 de maig 2019 a les 16:42:
Reply all
Reply to author
Forward
0 new messages