Reforma pohlaví, I guess
This commit is contained in:
		
							parent
							
								
									a301b122fd
								
							
						
					
					
						commit
						a3a9c629d8
					
				
					 9 changed files with 79 additions and 21 deletions
				
			
		|  | @ -504,7 +504,7 @@ class NahrajReseniView(LoginRequiredMixin, CreateView): | |||
| 
 | ||||
| 		EmailMessage( | ||||
| 			subject="Nové řešení k " + seznam_do_subjectu, | ||||
| 			body=f"Řešitel{ '' if resitel.pohlavi_muz else 'ka' } { resitel } právě nahrál{'' if resitel.pohlavi_muz else 'a' } nové řešení k { seznam }.\n\nHurá do opravování: { self.object.absolute_url() }", | ||||
| 			body=f"{resitel} posílá nové řešení k { seznam }.\n\nHurá do opravování: { self.object.absolute_url() }", | ||||
| 			from_email="submitovatko@mam.mff.cuni.cz", # FIXME: Chceme to mít radši tady, nebo v nastavení? | ||||
| 			to=list(prijemci), | ||||
| 		).send() | ||||
|  |  | |||
|  | @ -32,7 +32,7 @@ class UdajeForm(forms.Form): | |||
| 	jmeno = forms.CharField(label='Jméno', max_length=256, required=True) | ||||
| 	prezdivka_resitele = forms.CharField(label='Přezdívka (veřejná)', max_length=256, required=False) | ||||
| 	prijmeni = forms.CharField(label='Příjmení', max_length=256, required=True) | ||||
| 	pohlavi_muz = forms.ChoiceField(label='Pohlaví', choices=((True, 'muž'), (False, 'žena')), required=True) | ||||
| 	osloveni = forms.ChoiceField(label='Oslovení', choices=Osoba.OSLOVENI_CHOICES, required=False) | ||||
| 	email = forms.EmailField(label='E-mail', max_length=256, required=True) | ||||
| 	telefon = forms.CharField(widget=TelInput(), label='Telefon', max_length=256, required=False) | ||||
| 	datum_narozeni = forms.DateField(widget=DateInput(), label='Datum narození', required=False) | ||||
|  |  | |||
|  | @ -24,7 +24,7 @@ | |||
|   {% include "personalni/udaje/prihlaska_field.html" with field=form.jmeno %} | ||||
|   {% include "personalni/udaje/prihlaska_field.html" with field=form.prezdivka_resitele %} | ||||
|   {% include "personalni/udaje/prihlaska_field.html" with field=form.prijmeni %} | ||||
|   {% include "personalni/udaje/prihlaska_field.html" with field=form.pohlavi_muz%} | ||||
|   {% include "personalni/udaje/prihlaska_field.html" with field=form.osloveni%} | ||||
|   {% include "personalni/udaje/prihlaska_field.html" with field=form.email %} | ||||
|   {% include "personalni/udaje/prihlaska_field.html" with field=form.telefon %} | ||||
|   {% include "personalni/udaje/prihlaska_field.html" with field=form.datum_narozeni %} | ||||
|  |  | |||
|  | @ -139,7 +139,7 @@ def resitelEditView(request): | |||
| 			form_logger.info("EDIT:" + str(fcd) + str(form_hash))  # TODO možná logovat jinak | ||||
| 			osoba_edit.jmeno = fcd['jmeno'] | ||||
| 			osoba_edit.prijmeni = fcd['prijmeni'] | ||||
| 			osoba_edit.pohlavi_muz = fcd['pohlavi_muz'] | ||||
| 			osoba_edit.osloveni = fcd['osloveni'] | ||||
| 			osoba_edit.email = fcd['email'] | ||||
| 			osoba_edit.telefon = fcd['telefon'] | ||||
| 			osoba_edit.ulice = fcd['ulice'] | ||||
|  | @ -209,7 +209,7 @@ def prihlaskaView(request): | |||
| 				o = s.Osoba( | ||||
| 					jmeno = fcd['jmeno'], | ||||
| 					prijmeni = fcd['prijmeni'], | ||||
| 					pohlavi_muz = fcd['pohlavi_muz'], | ||||
| 					osloveni = fcd['osloveni'], | ||||
| 					email = fcd['email'], | ||||
| 					telefon = fcd.get('telefon',''), | ||||
| 					datum_narozeni = fcd.get('datum_narozeni',None), | ||||
|  | @ -242,7 +242,7 @@ def prihlaskaView(request): | |||
| 
 | ||||
| 				# Porovnání údajů | ||||
| 				assert orig_osoba.user is None, "Právě-registrující-se osoba už má Uživatele!" | ||||
| 				osoba_attrs = ['jmeno', 'prijmeni', 'pohlavi_muz', 'email', 'telefon', 'datum_narozeni', 'ulice', 'mesto', 'psc', 'stat', 'datum_souhlasu_udaje', 'datum_souhlasu_zasilani', 'datum_registrace'] | ||||
| 				osoba_attrs = ['jmeno', 'prijmeni', 'osloveni', 'email', 'telefon', 'datum_narozeni', 'ulice', 'mesto', 'psc', 'stat', 'datum_souhlasu_udaje', 'datum_souhlasu_zasilani', 'datum_registrace'] | ||||
| 				diffattrs = [] | ||||
| 				for attr in osoba_attrs: | ||||
| 					new = getattr(o, attr) | ||||
|  | @ -339,7 +339,7 @@ def dataResiteluCsvResponse(queryset, columns=None, with_header=True): | |||
| 		'osoba__telefon', | ||||
| 		'osoba__user__username', | ||||
| 		'osoba__datum_narozeni', | ||||
| 		'osoba__pohlavi_muz', | ||||
| 		'osoba__osloveni', | ||||
| 		'osoba__ulice', | ||||
| 		'osoba__mesto', | ||||
| 		'osoba__psc', | ||||
|  | @ -367,7 +367,7 @@ def dataResiteluCsvResponse(queryset, columns=None, with_header=True): | |||
| 		'osoba__telefon':                'telefon', | ||||
| 		'osoba__user__username':         'user', | ||||
| 		'osoba__datum_narozeni':         'datum_narozeni', | ||||
| 		'osoba__pohlavi_muz':            'pohlavi_muz', | ||||
| 		'osoba__osloveni':               'osloveni', | ||||
| 		'osoba__ulice':                  'ulice', | ||||
| 		'osoba__mesto':                  'mesto', | ||||
| 		'osoba__psc':                    'psc', | ||||
|  |  | |||
							
								
								
									
										40
									
								
								seminar/migrations/0115_reforma_pohlavi.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								seminar/migrations/0115_reforma_pohlavi.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,40 @@ | |||
| # Generated by Django 4.2.11 on 2024-04-12 14:03 | ||||
| 
 | ||||
| from django.db import migrations, models | ||||
| 
 | ||||
| # V migracích nemáme Osoba.OSLOVENI_*, tak si to sem nakopíruji. | ||||
| OSLOVENI_MUZSKE = 'resitel' | ||||
| OSLOVENI_ZENSKE = 'resitelka' | ||||
| OSLOVENI_ZADNE = '' | ||||
| 
 | ||||
| def pohlavi_to_osloveni(apps, schema_editor): | ||||
|     Osoba = apps.get_model('seminar', 'Osoba') | ||||
|     Osoba.objects.filter(pohlavi_muz=True).update(osloveni=OSLOVENI_MUZSKE) | ||||
|     Osoba.objects.filter(pohlavi_muz=False).update(osloveni=OSLOVENI_ZENSKE) | ||||
| 
 | ||||
| def osloveni_to_pohlavi(apps, schema_editor): | ||||
|     Osoba = apps.get_model('seminar', 'Osoba') | ||||
|     nebinarni = Osoba.objects.filter(osloveni=OSLOVENI_ZADNE) | ||||
|     if nebinarni.count() > 0: | ||||
|         raise Exception("Nelze odmigrovat: v databázi jsou nebinární osoby, které starý model nereprezentuje správně.") | ||||
|     Osoba.objects.filter(osloveni=OSLOVENI_MUZSKE).update(pohlavi_muz=True) | ||||
|     Osoba.objects.filter(osloveni=OSLOVENI_MUZSKE).update(pohlavi_muz=False) | ||||
| 
 | ||||
| class Migration(migrations.Migration): | ||||
| 
 | ||||
|     dependencies = [ | ||||
|         ('seminar', '0114_related_name_se_zmenilo_a_django_chce_migraci_tak_dostane_migraci'), | ||||
|     ] | ||||
| 
 | ||||
|     operations = [ | ||||
|         migrations.AddField( | ||||
|             model_name='osoba', | ||||
|             name='osloveni', | ||||
|             field=models.CharField(blank=True, choices=[('resitel', 'Řešitel'), ('resitelka', 'Řešitelka')], max_length=32, verbose_name='Oslovení'), | ||||
|         ), | ||||
|         migrations.RunPython(pohlavi_to_osloveni, osloveni_to_pohlavi), | ||||
|         migrations.RemoveField( | ||||
|             model_name='osoba', | ||||
|             name='pohlavi_muz', | ||||
|         ), | ||||
|     ] | ||||
|  | @ -38,8 +38,16 @@ class Osoba(SeminarModelBase): | |||
| 	user = models.OneToOneField(settings.AUTH_USER_MODEL, blank=True, null=True,  | ||||
| 				verbose_name='uživatel', on_delete=models.DO_NOTHING) | ||||
| 
 | ||||
| 	# Pohlaví. Že ho neznáme se snad nestane (a ušetří to práci při programování) | ||||
| 	pohlavi_muz = models.BooleanField('pohlaví (muž)', default=False) | ||||
| 	# Pohlaví nás prakticky nezajímá, reálně. | ||||
| 	OSLOVENI_MUZSKE = 'resitel' | ||||
| 	OSLOVENI_ZENSKE = 'resitelka' | ||||
| 	OSLOVENI_ZADNE = '' | ||||
| 	OSLOVENI_CHOICES = [ | ||||
| 			(OSLOVENI_MUZSKE, 'Řešitel'), | ||||
| 			(OSLOVENI_ZENSKE, 'Řešitelka'), | ||||
| 			(OSLOVENI_ZADNE, 'Cokoliv jiného'), # Reálně nás u nikoho jiného oslovení nezajímá? (A pohlaví už vůbec) | ||||
| 		] | ||||
| 	osloveni = models.CharField('Oslovení', choices=OSLOVENI_CHOICES, max_length=32, blank=True) | ||||
| 
 | ||||
| 	email = models.EmailField('e-mail', max_length=256, blank=True, default='') | ||||
| 
 | ||||
|  | @ -246,11 +254,19 @@ class Resitel(SeminarModelBase): | |||
| 
 | ||||
| 	def export_row(self): | ||||
| 		"Slovnik pro pouziti v AESOP exportu" | ||||
| 		# Ref: https://opmk.mff.cuni.cz/wiki/aesop/import#telo | ||||
| 
 | ||||
| 		# FUJ: Oslovení nemusí souviset s genderem. | ||||
| 		gender = { | ||||
| 			Osoba.OSLOVENI_MUZSKE: 'M', | ||||
| 			Osoba.OSLOVENI_ZENSKE: 'F', | ||||
| 			Osoba.OSLOVENI_ZADNE: '', | ||||
| 			}[self.osoba.osloveni] | ||||
| 		return { | ||||
| 			'id': self.id, | ||||
| 			'name': self.osoba.jmeno, | ||||
| 			'surname': self.osoba.prijmeni, | ||||
| 			'gender': 'M' if self.osoba.pohlavi_muz else 'F', | ||||
| 			'gender': gender, | ||||
| 			'born': self.osoba.datum_narozeni.isoformat() if self.osoba.datum_narozeni else '', | ||||
| 			'email': self.osoba.email, | ||||
| 			'end-year': self.rok_maturity or '', | ||||
|  |  | |||
|  | @ -58,17 +58,19 @@ def gen_osoby(rnd, size): | |||
| 	# 30 je náhodná konstanta, size je použité na víc místech a | ||||
| 	# říká, jak velká asi chceme testovací data | ||||
| 	for i in range(30 * size): | ||||
| 		pohlavi = rnd.randint(0,1) | ||||
| 		jmeno = rnd.choice([jmena_m, jmena_f][pohlavi]) | ||||
| 		prijmeni = rnd.choice([prijmeni_m, prijmeni_f][pohlavi]) | ||||
| 		pohlavi_idx = rnd.randint(0,2) # 2 = nebinární | ||||
| 		osloveni = [Osoba.OSLOVENI_MUZSKE, Osoba.OSLOVENI_ZENSKE, Osoba.OSLOVENI_ZADNE][pohlavi_idx] | ||||
| 		jmeno = rnd.choice([jmena_m, jmena_f, jmena_m + jmena_f][pohlavi_idx]) | ||||
| 		prijmeni = rnd.choice([prijmeni_m, prijmeni_f, prijmeni_m + prijmeni_f][pohlavi_idx]) | ||||
| 		if pohlavi_idx == 2: logger.debug(f'Testdata: nebinární osoba: {jmeno} {prijmeni}.') | ||||
| 		pokusy = 0 | ||||
| 		max_pokusy = 120*size | ||||
| 		while (not __unikatni_jmeno and pokusy < max_pokusy): | ||||
| 		# pokud jméno a příjmení není unikátní, zkoušíme generovat nová | ||||
| 		# do daného limitu (abychom se nezacyklili do nekonečna při málo jménech a příjmeních | ||||
| 		# ze kterých se generuje) | ||||
| 			jmeno = rnd.choice([jmena_m, jmena_f][pohlavi]) | ||||
| 			prijmeni = rnd.choice([prijmeni_m, prijmeni_f][pohlavi]) | ||||
| 			jmeno = rnd.choice([jmena_m, jmena_f, jmena_m + jmena_f][pohlavi_idx]) | ||||
| 			prijmeni = rnd.choice([prijmeni_m, prijmeni_f, prijmeni_m + prijmeni_f][pohlavi_idx]) | ||||
| 			pokusy = pokusy + 1 | ||||
| 		if pokusy >= max_pokusy: | ||||
| 			print("Chyba, na danou velikost testovacích dat příliš málo možných" | ||||
|  | @ -86,7 +88,7 @@ def gen_osoby(rnd, size): | |||
| 		psc = "".join([str(rnd.choice([k for k in range(10)])) for i in range(5)]) | ||||
| 
 | ||||
| 		osoby.append(Osoba.objects.create(jmeno = jmeno, prijmeni = prijmeni, | ||||
| 				prezdivka = prezdivka, pohlavi_muz = pohlavi, email = email, | ||||
| 				prezdivka = prezdivka, osloveni = osloveni, email = email, | ||||
| 				telefon = telefon, datum_narozeni = narozeni, ulice = ulice, | ||||
| 				mesto = mesto, psc = psc, | ||||
| 				datum_registrace = datetime.date(rnd.randint(2019, 2029), | ||||
|  | @ -818,7 +820,7 @@ def create_test_data(size = 6, rnd = None): | |||
| 	admin = User.objects.create_superuser(username='admin', email='', password='admin') | ||||
| 	os_admin = Osoba.objects.create( | ||||
| 		user=admin, jmeno='admin', prijmeni='admin', | ||||
| 		prezdivka='admin', pohlavi_muz=1, email='admin@admin.admin', | ||||
| 		prezdivka='admin', osloveni='', email='admin@admin.admin', | ||||
| 		telefon='123 456 789', datum_narozeni=datetime.date(2000, 1, 1), | ||||
| 		ulice='admin', mesto='admin', psc='100 00', | ||||
| 		datum_registrace=datetime.date(2020, 9, 6) | ||||
|  |  | |||
|  | @ -337,7 +337,7 @@ def merge_osoby(cilova, zdrojova): | |||
| 	# ID, User neřešíme, poznámku vyřešíme separátně. | ||||
| 	fieldy = ['datum_narozeni', 'datum_registrace', 'datum_souhlasu_udaje', | ||||
| 			'datum_souhlasu_zasilani', 'email', 'foto', 'jmeno', 'mesto', | ||||
| 			'pohlavi_muz', 'prezdivka', 'prijmeni', 'psc', 'stat', 'telefon', 'ulice'] | ||||
| 			'osloveni', 'prezdivka', 'prijmeni', 'psc', 'stat', 'telefon', 'ulice'] | ||||
| 	for f in fieldy: | ||||
| 		zf = getattr(zdrojova, f) | ||||
| 		cf = getattr(cilova, f) | ||||
|  |  | |||
|  | @ -674,8 +674,8 @@ class ClankyResitelView(generic.ListView): | |||
| def StavDatabazeView(request): | ||||
| #	nastaveni = Nastaveni.objects.get() | ||||
| 	problemy = utils.seznam_problemu() | ||||
| 	muzi = Resitel.objects.filter(osoba__pohlavi_muz=True) | ||||
| 	zeny = Resitel.objects.filter(osoba__pohlavi_muz=False) | ||||
| 	muzi = Resitel.objects.filter(osoba__osloveni=m.Osoba.OSLOVENI_MUZSKE) | ||||
| 	zeny = Resitel.objects.filter(osoba__osloveni=m.Osoba.OSLOVENI_ZENSKE) | ||||
| 	return render(request, 'seminar/stav_databaze.html', | ||||
| 			{ | ||||
| #				'nastaveni': nastaveni, | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Pavel "LEdoian" Turinsky
						Pavel "LEdoian" Turinsky