views_all | filtrování json-u podle práv uživatele
This commit is contained in:
		
							parent
							
								
									440f40fc82
								
							
						
					
					
						commit
						0ebc9b5f32
					
				
					 3 changed files with 73 additions and 51 deletions
				
			
		|  | @ -745,15 +745,18 @@ class Problem(SeminarModelBase,PolymorphicModel): | ||||||
| 	def verejne(self): | 	def verejne(self): | ||||||
| 		# aktuálně podle stavu problému | 		# aktuálně podle stavu problému | ||||||
| 		# FIXME pro některé problémy možná chceme override | 		# FIXME pro některé problémy možná chceme override | ||||||
|  | 		# FIXME vrací veřejnost čistě problému, nezávisle na čísle, ve kterém je.  | ||||||
|  | 		# Je to tak správně? | ||||||
| 		stav_verejny = False | 		stav_verejny = False | ||||||
| 		if self.stav == 'zadany' or self.stav == 'vyreseny': | 		if self.stav == 'zadany' or self.stav == 'vyreseny': | ||||||
| 			stav_verejny = True | 			stav_verejny = True | ||||||
|  | 		return stav_verejny | ||||||
| 		 | 		 | ||||||
| 		cislo_verejne = False | 		#cislo_verejne = False | ||||||
| 		if (self.cislo_zadani and self.cislo_zadani.verejne()): | 		#if (self.cislo_zadani and self.cislo_zadani.verejne()): | ||||||
| 			cislo_verejne = True | 		#	cislo_verejne = True | ||||||
| 		 | 		 | ||||||
| 		return (stav_verejny and cislo_verejne) | 		#return (stav_verejny and cislo_verejne) | ||||||
| 	verejne.boolean = True | 	verejne.boolean = True | ||||||
| 
 | 
 | ||||||
| 	def verejne_url(self): | 	def verejne_url(self): | ||||||
|  |  | ||||||
|  | @ -1,4 +1,4 @@ | ||||||
| # coding:utf-8 | 
 | ||||||
| 
 | 
 | ||||||
| from django.shortcuts import get_object_or_404, render, redirect | from django.shortcuts import get_object_or_404, render, redirect | ||||||
| from django.http import HttpResponse, HttpResponseRedirect, HttpResponseForbidden, JsonResponse | from django.http import HttpResponse, HttpResponseRedirect, HttpResponseForbidden, JsonResponse | ||||||
|  | @ -17,6 +17,7 @@ from django.contrib.auth.models import User, Permission | ||||||
| from django.contrib.auth.mixins import LoginRequiredMixin | from django.contrib.auth.mixins import LoginRequiredMixin | ||||||
| from django.db import transaction | from django.db import transaction | ||||||
| from django.core import serializers | from django.core import serializers | ||||||
|  | from django.core.exceptions import PermissionDenied | ||||||
| from django.forms.models import model_to_dict | from django.forms.models import model_to_dict | ||||||
| 
 | 
 | ||||||
| import seminar.models as s | import seminar.models as s | ||||||
|  | @ -120,15 +121,57 @@ class TNLData(object): | ||||||
| 			self.appendable_siblings = tnltt.appendableChildren(self.parent) | 			self.appendable_siblings = tnltt.appendableChildren(self.parent) | ||||||
| 		else: | 		else: | ||||||
| 			self.appendable_siblings = [] | 			self.appendable_siblings = [] | ||||||
|  | 	@classmethod | ||||||
|  | 	def public_above(cls, anode): | ||||||
|  | 		""" Returns output of verejne for closest Rocnik, Cislo or Problem above. | ||||||
|  | 		(All of them have method verejne.)""" | ||||||
|  | 		parent = anode # chceme začít už od konkrétního node včetně | ||||||
|  | 		while True: | ||||||
|  | 			rocnik = isinstance(parent, s.RocnikNode) | ||||||
|  | 			cislo = isinstance(parent, s.CisloNode) | ||||||
|  | 			uloha = (isinstance(parent, s.UlohaVzorakNode) or  | ||||||
|  | 				isinstance(parent, s.UlohaZadaniNode)) | ||||||
|  | 			tema = isinstance(parent, s.TemaVCisleNode) | ||||||
| 
 | 
 | ||||||
| 
 | 			if (rocnik or cislo or uloha or tema) or parent==None: | ||||||
|  | 				break | ||||||
|  | 			else: | ||||||
|  | 				parent = treelib.get_parent(parent) | ||||||
|  | 		if rocnik: | ||||||
|  | 			return parent.rocnik.verejne() | ||||||
|  | 		elif cislo: | ||||||
|  | 			return parent.cislo.verejne() | ||||||
|  | 		elif uloha: | ||||||
|  | 			return parent.uloha.verejne() | ||||||
|  | 		elif tema: | ||||||
|  | 			return parent.tema.verejne() | ||||||
|  | 		elif None: | ||||||
|  | 			print("Existuje TreeNode, který není pod číslem, ročníkem, úlohou" | ||||||
|  | 			"ani tématem. {}".format(anode)) | ||||||
|  | 			return False | ||||||
|  | 	 | ||||||
|  | 	@classmethod | ||||||
|  | 	def all_public_children(cls, anode): | ||||||
|  | 		for ch in treelib.all_children(anode): | ||||||
|  | 			if TNLData.public_above(ch): | ||||||
|  | 				yield ch | ||||||
|  | 			else: | ||||||
|  | 				continue | ||||||
| 
 | 
 | ||||||
| 	@classmethod | 	@classmethod | ||||||
| 	def from_treenode(cls,anode,parent=None,index=None): | 	def from_treenode(cls, anode, user, parent=None, index=None): | ||||||
| 		out = cls(anode,parent,index) | 		if TNLData.public_above(anode) or user.has_perm('auth.org'): | ||||||
| 		for (idx,ch) in enumerate(treelib.all_children(anode)): | 			out = cls(anode,parent,index) | ||||||
| 			# FIXME přidat filtrování na veřejnost | 		else: | ||||||
| 			outitem = cls.from_treenode(ch,out,idx) | 			raise PermissionDenied() | ||||||
|  | 
 | ||||||
|  | 		if user.has_perm('auth.org'): | ||||||
|  | 			enum_children = enumerate(treelib.all_children(anode)) | ||||||
|  | 		else: | ||||||
|  | 			enum_children = enumerate(TNLData.all_public_children(anode))	 | ||||||
|  | 	 | ||||||
|  | 		for (idx,ch) in enum_children: | ||||||
|  | 			outitem = cls.from_treenode(ch, user, out,  idx) | ||||||
| 			out.children.append(outitem) | 			out.children.append(outitem) | ||||||
| 		out.add_edit_options() | 		out.add_edit_options() | ||||||
| 		return out | 		return out | ||||||
|  | @ -195,7 +238,7 @@ class TreeNodeView(generic.DetailView): | ||||||
| 
 | 
 | ||||||
| 	def get_context_data(self,**kwargs): | 	def get_context_data(self,**kwargs): | ||||||
| 		context = super().get_context_data(**kwargs) | 		context = super().get_context_data(**kwargs) | ||||||
| 		context['tnldata'] = TNLData.from_treenode(self.object) | 		context['tnldata'] = TNLData.from_treenode(self.object,self.request.user) | ||||||
| 		return context | 		return context | ||||||
| 
 | 
 | ||||||
| class TreeNodeJSONView(generic.DetailView): | class TreeNodeJSONView(generic.DetailView): | ||||||
|  | @ -203,7 +246,7 @@ class TreeNodeJSONView(generic.DetailView): | ||||||
| 
 | 
 | ||||||
| 	def get(self,request,*args, **kwargs): | 	def get(self,request,*args, **kwargs): | ||||||
| 		self.object = self.get_object() | 		self.object = self.get_object() | ||||||
| 		data = TNLData.from_treenode(self.object).to_json() | 		data = TNLData.from_treenode(self.object,self.request.user).to_json() | ||||||
| 		return JsonResponse(data) | 		return JsonResponse(data) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -332,6 +375,7 @@ class ProblemView(generic.DetailView): | ||||||
| 
 | 
 | ||||||
| 	def get_context_data(self, **kwargs): | 	def get_context_data(self, **kwargs): | ||||||
| 		context = super().get_context_data(**kwargs) | 		context = super().get_context_data(**kwargs) | ||||||
|  | 		user = self.request.user | ||||||
| 		# Teď potřebujeme doplnit tnldata do kontextu. | 		# Teď potřebujeme doplnit tnldata do kontextu. | ||||||
| 		# Ošklivý type switch, hezčí by bylo udělat to polymorfni. FIXME. | 		# Ošklivý type switch, hezčí by bylo udělat to polymorfni. FIXME. | ||||||
| 		if False: | 		if False: | ||||||
|  | @ -339,11 +383,11 @@ class ProblemView(generic.DetailView): | ||||||
| 			pass | 			pass | ||||||
| 		elif isinstance(self.object, s.Clanek) or  isinstance(self.object, s.Konfera): | 		elif isinstance(self.object, s.Clanek) or  isinstance(self.object, s.Konfera): | ||||||
| 			# Tyhle Problémy mají ŘešeníNode | 			# Tyhle Problémy mají ŘešeníNode | ||||||
| 			context['tnldata'] = TNLData.from_treenode(self.object.reseninode) | 			context['tnldata'] = TNLData.from_treenode(self.object.reseninode,user) | ||||||
| 		elif isinstance(self.object, s.Uloha): | 		elif isinstance(self.object, s.Uloha): | ||||||
| 			# FIXME: Teď vždycky zobrazujeme i vzorák! Možná by bylo hezčí/lepší mít to stejně jako pro Téma: procházet jen dosažitelné z Ročníku / čísla / whatever | 			# FIXME: Teď vždycky zobrazujeme i vzorák! Možná by bylo hezčí/lepší mít to stejně jako pro Téma: procházet jen dosažitelné z Ročníku / čísla / whatever | ||||||
| 			tnl_zadani = TNLData.from_treenode(self.object.ulohazadaninode) | 			tnl_zadani = TNLData.from_treenode(self.object.ulohazadaninode,user) | ||||||
| 			tnl_vzorak = TNLData.from_treenode(self.object.ulohavzoraknode) | 			tnl_vzorak = TNLData.from_treenode(self.object.ulohavzoraknode,user) | ||||||
| 			context['tnldata'] = TNLData.from_tnldata_list([tnl_zadani, tnl_vzorak]) | 			context['tnldata'] = TNLData.from_tnldata_list([tnl_zadani, tnl_vzorak]) | ||||||
| 		elif isinstance(self.object, s.Tema): | 		elif isinstance(self.object, s.Tema): | ||||||
| 			rocniknode = self.object.rocnik.rocniknode | 			rocniknode = self.object.rocnik.rocniknode | ||||||
|  | @ -385,16 +429,16 @@ class AktualniZadaniView(generic.TemplateView): | ||||||
| #			) | #			) | ||||||
| # | # | ||||||
| def ZadaniTemataView(request): | def ZadaniTemataView(request): | ||||||
|         nastaveni = get_object_or_404(Nastaveni) | 	nastaveni = get_object_or_404(Nastaveni) | ||||||
|         verejne = nastaveni.aktualni_cislo.verejne() | 	verejne = nastaveni.aktualni_cislo.verejne() | ||||||
|         akt_rocnik = nastaveni.aktualni_cislo.rocnik | 	akt_rocnik = nastaveni.aktualni_cislo.rocnik | ||||||
|         temata = s.Tema.objects.filter(rocnik=akt_rocnik, stav='zadany') | 	temata = s.Tema.objects.filter(rocnik=akt_rocnik, stav='zadany') | ||||||
|         return render(request, 'seminar/tematka/rozcestnik.html', | 	return render(request, 'seminar/tematka/rozcestnik.html', | ||||||
|                         { | 			{ | ||||||
|                          'tematka': temata, | 			 'tematka': temata, | ||||||
|                          'verejne': verejne, | 			 'verejne': verejne, | ||||||
|                                 }, | 				}, | ||||||
|                         ) | 			) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| #	nastaveni = get_object_or_404(Nastaveni) | #	nastaveni = get_object_or_404(Nastaveni) | ||||||
|  |  | ||||||
|  | @ -18,31 +18,6 @@ class PermissionMixin(object): | ||||||
| 		# návštěvník nemusí být zalogován, aby si prohlížel obsah | 		# návštěvník nemusí být zalogován, aby si prohlížel obsah | ||||||
| 		return [permission() for permission in permission_classes] | 		return [permission() for permission in permission_classes] | ||||||
| 
 | 
 | ||||||
| 	def verejne_nad(self, node): |  | ||||||
| 		""" Returns output of verejne for closest Rocnik, Cislo or Problem above. |  | ||||||
| 		(All of them have method verejne.)""" |  | ||||||
| 		parent = get_parent(node) |  | ||||||
| 		while True: |  | ||||||
| 			rocnik = isinstance(parent, RocnikNode) |  | ||||||
| 			cislo = isinstance(parent, CisloNode) |  | ||||||
| 			problem = isinstance(parent, ProblemNode) |  | ||||||
| 
 |  | ||||||
| 			if (rocnik or cislo or problem): |  | ||||||
| 				break |  | ||||||
| 			else: |  | ||||||
| 				parent = get_parent(parent) |  | ||||||
| 		if rocnik: |  | ||||||
| 			return parent.rocnik.verejne() |  | ||||||
| 		elif cislo: |  | ||||||
| 			return parent.cislo.verejne() |  | ||||||
| 		elif problem: |  | ||||||
| 			return parent.problem.verjne() |  | ||||||
| 
 |  | ||||||
| 	def has_object_permission(self, request, view, obj): |  | ||||||
| 		# test that obj is Node |  | ||||||
| 		assert isinstance(obj, Node) |  | ||||||
| 		return verejne_nad(node) |  | ||||||
| 
 |  | ||||||
| class ReadWriteSerializerMixin(object): | class ReadWriteSerializerMixin(object): | ||||||
| 	""" | 	""" | ||||||
| 	Overrides get_serializer_class to choose the read serializer | 	Overrides get_serializer_class to choose the read serializer | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Aneta Pokorná
						Aneta Pokorná