55{% block content %}
66< div class ="row ">
77 < div class ="col-12 ">
8- < div class ="card mb-4 ">
9- < div class ="card-header ">
8+ < div class ="card mb-4 " style =" border: 3px solid #28a745; background: linear-gradient(45deg, #f8f9fa, #e9ecef); " >
9+ < div class ="card-header " style =" background: linear-gradient(45deg, #28a745, #20c997); color: white; " >
1010 < h4 class ="mb-0 ">
11- < i class ="fas fa-code me-2 "> </ i > {{ demo_title }}
11+ < i class ="fas fa-code me-2 "> </ i > Context Manager Demo
1212 </ h4 >
1313 </ div >
1414 < div class ="card-body ">
@@ -31,7 +31,12 @@ <h5 class="mb-0">
3131 </ div >
3232 < div class ="card-body ">
3333 < p class ="small text-muted "> Direct database queries without anonymization:</ p >
34- < pre class ="bg-light p-2 rounded "> < code > User.objects.values('username', 'email')[:5]</ code > </ pre >
34+ < div class ="code-block " style ="position: relative; ">
35+ < pre style ="background: #f6f8fa; border: 1px solid #e1e4e8; border-radius: 6px; padding: 16px; margin: 0; font-family: 'SFMono-Regular', Consolas, monospace; font-size: 13px; line-height: 1.45; "> < code > User.objects.< span style ="color: #6f42c1; font-weight: 600; "> values</ span > (< span style ="color: #032f62; "> 'username'</ span > , < span style ="color: #032f62; "> 'email'</ span > )[< span style ="color: #005cc5; "> :</ span > < span style ="color: #005cc5; "> 5</ span > ]</ code > </ pre >
36+ < button onclick ="copyCode(this) " style ="position: absolute; top: 8px; right: 8px; background: #0366d6; color: white; border: none; border-radius: 4px; padding: 4px 8px; font-size: 11px; cursor: pointer; opacity: 0.7; " title ="Copy code ">
37+ Copy
38+ </ button >
39+ </ div >
3540
3641 < div class ="mt-3 ">
3742 {% for user in normal_data %}
@@ -58,10 +63,15 @@ <h5 class="mb-0">
5863 </ div >
5964 < div class ="card-body ">
6065 < p class ="small text-muted "> Using < code > anonymized_data()</ code > context manager:</ p >
61- < pre class ="bg-light p-2 rounded "> < code > from django_postgres_anon.context_managers import anonymized_data
62-
63- with anonymized_data():
64- User.objects.values('username', 'email')[:5]</ code > </ pre >
66+ < div style ="position: relative; ">
67+ < pre style ="background: #f6f8fa; border: 1px solid #e1e4e8; border-radius: 6px; padding: 16px; margin: 0; font-family: 'SFMono-Regular', Consolas, monospace; font-size: 13px; line-height: 1.45; "> < code > < span style ="color: #d73a49; font-weight: 600; "> from</ span > django_postgres_anon.context_managers < span style ="color: #d73a49; font-weight: 600; "> import</ span > anonymized_data
68+
69+ < span style ="color: #d73a49; font-weight: 600; "> with</ span > < span style ="color: #6f42c1; "> anonymized_data</ span > ():
70+ User.objects.< span style ="color: #6f42c1; "> values</ span > (< span style ="color: #032f62; "> 'username'</ span > , < span style ="color: #032f62; "> 'email'</ span > )[< span style ="color: #005cc5; "> :</ span > < span style ="color: #005cc5; "> 5</ span > ]</ code > </ pre >
71+ < button onclick ="copyCode(this) " style ="position: absolute; top: 8px; right: 8px; background: #0366d6; color: white; border: none; border-radius: 4px; padding: 4px 8px; font-size: 11px; cursor: pointer; opacity: 0.7; " title ="Copy code ">
72+ Copy
73+ </ button >
74+ </ div >
6575
6676 < div class ="mt-3 ">
6777 {% for user in anonymized_data %}
@@ -94,10 +104,15 @@ <h5 class="mb-0">
94104 </ div >
95105 < div class ="card-body ">
96106 < p class ="small text-muted "> Using < code > database_role()</ code > context manager:</ p >
97- < pre class ="bg-light p-2 rounded "> < code > from django_postgres_anon.context_managers import database_role
98-
99- with database_role('masked_reader'):
100- User.objects.values('username', 'email')[:5]</ code > </ pre >
107+ < div style ="position: relative; ">
108+ < pre style ="background: #f6f8fa; border: 1px solid #e1e4e8; border-radius: 6px; padding: 16px; margin: 0; font-family: 'SFMono-Regular', Consolas, monospace; font-size: 13px; line-height: 1.45; "> < code > < span style ="color: #d73a49; font-weight: 600; "> from</ span > django_postgres_anon.context_managers < span style ="color: #d73a49; font-weight: 600; "> import</ span > database_role
109+
110+ < span style ="color: #d73a49; font-weight: 600; "> with</ span > < span style ="color: #6f42c1; "> database_role</ span > (< span style ="color: #032f62; "> 'masked_reader'</ span > ):
111+ User.objects.< span style ="color: #6f42c1; "> values</ span > (< span style ="color: #032f62; "> 'username'</ span > , < span style ="color: #032f62; "> 'email'</ span > )[< span style ="color: #005cc5; "> :</ span > < span style ="color: #005cc5; "> 5</ span > ]</ code > </ pre >
112+ < button onclick ="copyCode(this) " style ="position: absolute; top: 8px; right: 8px; background: #0366d6; color: white; border: none; border-radius: 4px; padding: 4px 8px; font-size: 11px; cursor: pointer; opacity: 0.7; " title ="Copy code ">
113+ Copy
114+ </ button >
115+ </ div >
101116
102117 < div class ="mt-3 ">
103118 {% for user in role_switched_data %}
@@ -125,97 +140,72 @@ <h5 class="mb-0">
125140< div class ="row ">
126141 < div class ="col-12 ">
127142 < div class ="card mb-4 ">
128- < div class ="card-header bg-info text- white ">
143+ < div class ="card-header " style =" background: linear-gradient(45deg, #17a2b8, #138496); color: white; ">
129144 < h5 class ="mb-0 ">
130- < i class ="fas fa-copy me-2 "> </ i > Quick Start - Copy & Paste Ready
145+ < i class ="fas fa-copy me-2 "> </ i > ✨ Quick Start - Copy & Paste Ready
131146 </ h5 >
132147 </ div >
133148 < div class ="card-body ">
134149 < p class ="mb-3 "> Ready to use this in your project? Copy and paste this code:</ p >
135- < pre class ="bg-light p-3 rounded "> < code > # Import the context managers
136- from django_postgres_anon.context_managers import anonymized_data, database_role
137-
138- # Basic usage in your views
139- def my_view(request):
140- # Get anonymized data
141- with anonymized_data():
142- users = User.objects.all()
143-
144- # Or use specific role
145- with database_role('masked_reader'):
146- customers = Customer.objects.all()
147-
148- return render(request, 'template.html', {'users': users})</ code > </ pre >
149- </ div >
150- </ div >
151- </ div >
152- </ div >
153-
154- <!-- Code Examples -->
155- < div class ="row ">
156- < div class ="col-12 ">
157- < div class ="card ">
158- < div class ="card-header ">
159- < h5 class ="mb-0 ">
160- < i class ="fas fa-code me-2 "> </ i > Implementation Examples
161- </ h5 >
162- </ div >
163- < div class ="card-body ">
164- < div class ="row ">
165- < div class ="col-md-6 ">
166- < h6 > Context Manager Usage</ h6 >
167- < pre class ="bg-light p-3 rounded "> < code > # Temporary anonymized access
168- from django_postgres_anon.context_managers import anonymized_data
169-
170- def my_view(request):
171- # Normal data access
172- normal_users = User.objects.all()
173-
174- # Anonymized data access
175- with anonymized_data():
176- anon_users = User.objects.all()
177-
178- return render(request, 'template.html', {
179- 'normal': normal_users,
180- 'anonymized': anon_users
181- })</ code > </ pre >
182- </ div >
183- < div class ="col-md-6 ">
184- < h6 > Role Switching</ h6 >
185- < pre class ="bg-light p-3 rounded "> < code > # Switch to specific database role
186- from django_postgres_anon.context_managers import database_role
187-
188- def admin_view(request):
189- # Switch to masked reader role
190- with database_role('masked_reader'):
191- sensitive_data = Customer.objects.all()
192-
193- # Back to normal role
194- normal_data = Customer.objects.all()
195-
196- return render(request, 'admin.html', {
197- 'masked': sensitive_data,
198- 'normal': normal_data
199- })</ code > </ pre >
200- </ div >
150+ < div style ="position: relative; ">
151+ < pre style ="background: #f6f8fa; border: 1px solid #e1e4e8; border-radius: 6px; padding: 16px; margin: 0; font-family: 'SFMono-Regular', Consolas, monospace; font-size: 13px; line-height: 1.45; "> < code > < span style ="color: #6a737d; font-style: italic; "> # Import the context managers</ span >
152+ < span style ="color: #d73a49; font-weight: 600; "> from</ span > django_postgres_anon.context_managers < span style ="color: #d73a49; font-weight: 600; "> import</ span > anonymized_data, database_role
153+
154+ < span style ="color: #6a737d; font-style: italic; "> # Basic usage in your views</ span >
155+ < span style ="color: #d73a49; font-weight: 600; "> def</ span > < span style ="color: #6f42c1; "> my_view</ span > (request):
156+ < span style ="color: #6a737d; font-style: italic; "> # Get anonymized data</ span >
157+ < span style ="color: #d73a49; font-weight: 600; "> with</ span > < span style ="color: #6f42c1; "> anonymized_data</ span > ():
158+ users = User.objects.< span style ="color: #6f42c1; "> all</ span > ()
159+
160+ < span style ="color: #6a737d; font-style: italic; "> # Or use specific role</ span >
161+ < span style ="color: #d73a49; font-weight: 600; "> with</ span > < span style ="color: #6f42c1; "> database_role</ span > (< span style ="color: #032f62; "> 'masked_reader'</ span > ):
162+ customers = Customer.objects.< span style ="color: #6f42c1; "> all</ span > ()
163+
164+ < span style ="color: #d73a49; font-weight: 600; "> return</ span > < span style ="color: #6f42c1; "> render</ span > (request, < span style ="color: #032f62; "> 'template.html'</ span > , {< span style ="color: #032f62; "> 'users'</ span > : users})</ code > </ pre >
165+ < button onclick ="copyCode(this) " style ="position: absolute; top: 8px; right: 8px; background: #0366d6; color: white; border: none; border-radius: 4px; padding: 4px 8px; font-size: 11px; cursor: pointer; opacity: 0.7; " title ="Copy code ">
166+ Copy
167+ </ button >
201168 </ div >
202169 </ div >
203170 </ div >
204171 </ div >
205172</ div >
206173
207- <!-- Navigation -->
208- < div class ="row mt-4 ">
209- < div class ="col-12 text-center ">
210- < a href ="{% url 'sample_app:anonymization_demo' %} " class ="btn btn-outline-primary me-2 ">
211- < i class ="fas fa-arrow-left me-1 "> </ i > Back to Demo
212- </ a >
213- < a href ="/api/decorated-users/ " class ="btn btn-primary me-2 " target ="_blank ">
214- < i class ="fas fa-external-link-alt me-1 "> </ i > Try Decorator API
215- </ a >
216- < a href ="{% url 'sample_app:function_validator_demo' %} " class ="btn btn-success ">
217- < i class ="fas fa-check-circle me-1 "> </ i > Function Validator
218- </ a >
219- </ div >
220- </ div >
221- {% endblock %}
174+ < script >
175+ function copyCode ( button ) {
176+ const codeBlock = button . previousElementSibling . querySelector ( 'code' ) ;
177+ const text = codeBlock . textContent ;
178+
179+ navigator . clipboard . writeText ( text ) . then ( function ( ) {
180+ const originalText = button . textContent ;
181+ button . textContent = 'Copied!' ;
182+ button . style . background = '#28a745' ;
183+ button . style . opacity = '1' ;
184+
185+ setTimeout ( function ( ) {
186+ button . textContent = originalText ;
187+ button . style . background = '#0366d6' ;
188+ button . style . opacity = '0.7' ;
189+ } , 2000 ) ;
190+ } ) . catch ( function ( err ) {
191+ const textArea = document . createElement ( 'textarea' ) ;
192+ textArea . value = text ;
193+ document . body . appendChild ( textArea ) ;
194+ textArea . select ( ) ;
195+ document . execCommand ( 'copy' ) ;
196+ document . body . removeChild ( textArea ) ;
197+
198+ const originalText = button . textContent ;
199+ button . textContent = 'Copied!' ;
200+ button . style . background = '#28a745' ;
201+ button . style . opacity = '1' ;
202+
203+ setTimeout ( function ( ) {
204+ button . textContent = originalText ;
205+ button . style . background = '#0366d6' ;
206+ button . style . opacity = '0.7' ;
207+ } , 2000 ) ;
208+ } ) ;
209+ }
210+ </ script >
211+ {% endblock %}
0 commit comments