class Initiative(models.Model): """Model to represent Initiative objects""" name = models.CharField( _('Nombre de la iniciativa'), max_length=200, blank=False, null=True, help_text=_('¿Cuál es el nombre de tu iniciativa?')) slug = models.SlugField(editable=False, blank=True) creation_date = models.DateField(editable=False, default=timezone.now) featured = models.BooleanField( _('Destacado'), blank=True, default=False, help_text=_('Indica si es una iniciativa destacada')) user = models.ForeignKey(User, verbose_name=_('Gestor'), blank=True, null=True, on_delete=models.SET_NULL) image = models.ImageField( _("Imagen"), blank=True, validators=[validate_image_size, validate_image_type], upload_to=initiatives_images_path, help_text= _("Sube una imagen representativa de la iniciativa haciendo click en la imagen inferior. " "La imagen ha de tener ancho mínimo de 300 píxeles y máximo de 1920, y altura mínima " "de 300 píxeles y máxima de 1280. Formatos permitidos: PNG, JPG, JPEG." )) image_medium = ImageSpecField( source="image", processors=[processors.ResizeToFill(600, 300)], format='JPEG', options={'quality': 90}) video = models.CharField( _('Video'), max_length=200, blank=True, null=True, help_text=_('Inserta la url de un video de Youtube o Vimeo')) description = models.TextField( _('Descripción de la iniciativa'), blank=False, null=True, help_text=_('Describe los objetivos y actividad de la iniciativa.')) website = models.URLField( _('Website'), blank=True, null=True, help_text=_( 'Especifica opcionalmente una web para conocer mejor la iniciativa.' )) twitter = models.CharField( _('Twitter'), blank=True, null=True, max_length=128, help_text=_( 'Si tienes una cuenta de Twitter, pon aquí el nombre de usuario.')) facebook = models.URLField( _('Facebook'), blank=True, null=True, help_text= _('Si tienes un perfil de Facebook pon aquí el enlace completo a la misma.' )) email = models.EmailField( _('Correo electrónico'), blank=False, null=True, help_text=_('Especifica un correo de contacto para la iniciativa.')) topic = models.CharField(_('Tema'), blank=False, null=False, default='DC', max_length=2, choices=categories.TOPICS, help_text=_('El tema de la iniciativa')) space = models.CharField( _('Tipo de espacio'), blank=False, null=False, default='CC', max_length=2, choices=categories.SPACES, help_text=_('El tipo de espacio asociado a la iniciativa')) agent = models.CharField( _('tipo de agente'), blank=False, null=False, default='IM', max_length=2, choices=categories.AGENTS, help_text=_('El tipo de agente involucrado en la iniciativa')) city = models.ForeignKey( City, verbose_name=_('Ciudad'), blank=False, null=True, on_delete=models.SET_NULL, help_text= _('Ciudad donde se encuentra la iniciativa. Si no encuentras la ciudad en el desplegable usa el botón inferior para añadir una nueva ciudad y seleccionarla' )) address = models.CharField( _('Dirección'), max_length=200, blank=False, null=True, help_text= _('Dirección de la iniciativa. No es necesario que vuelvas a introducir la ciudad de la iniciativa.' )) district = models.CharField( _('Distrito'), max_length=200, blank=True, null=True, help_text=_('¿En qué barrio de la ciudad se sitúa la iniciativa?')) position = PointField( _("Ubicación"), blank=False, null=True, help_text= _("Tras añadir ciudad y dirección puedes ubicar la iniciativa pulsando el botón inferior y ajustando la posición del marcador posteriormente." )) class Meta: verbose_name = _('Iniciativa') verbose_name_plural = _('Iniciativas') def __str__(self): """String representation of this model objects.""" return self.name or '---' @property def translated_name(self): print(self.request) @property def external_url(self): """Returns the first occurence of an external url related to the initiative""" if self.website: return self.website elif self.facebook: return self.facebook return "https://twitter.com/" + self.twitter def save(self, *args, **kwargs): """Populate automatically 'slug' field""" self.slug = slugify(self.name) # Notify by mail, only when creating new content if not self.id: send_mail( 'Creada la iniciativa \"' + self.name + "\"", 'Creada el ' + self.creation_date.strftime("%d/%b/%Y") + ' por ' + self.user.username + '\n---\n' + self.name + ' (' + self.email + '):\n' + self.description + '\n---\n' + 'Ciudad: ' + self.city.name, 'civics.cc <*****@*****.**>', settings.NOTIFICATIONS_EMAILS, fail_silently=False, ) super(Initiative, self).save(*args, **kwargs) def edit_permissions(self, user): """Returns users allowed to edit an instance of this model.""" if user.is_staff or (self.user and self.user == user): return True return False
class Record(models.Model): class Meta: verbose_name = "HRD Record" def __unicode__(self): return "%s (%s)" % (self.person_id, self.name) # Additional model valiation def clean(self): super(Record, self).clean() if self.date_govreply and not self.govreply_content: raise ValidationError( 'With a government reply date set, a reply content is required' ) if self.date_govaction and not self.govreply_action: raise ValidationError( 'With a government reply date set, a reply content is required' ) if self.type_intervention == 'JUA' or self.type_intervention == 'JAL': if not self.joint_with or (len(self.joint_with) == 1 and not self.joint_with[0]): raise ValidationError( 'Select joint intervention type, required for JUA and JAL.' ) # Communication dates: check for sensible time order if self.date_govreply and self.date_intervention and self.date_govreply < self.date_intervention: raise ValidationError( 'Date of government reply has to be past the date of intervention.' ) if self.date_intervention and self.date_incident and self.date_intervention < self.date_incident: raise ValidationError( 'Date of intervention has to be past the date of the incident.' ) if self.date_govreply and self.date_incident and self.date_govreply < self.date_incident: raise ValidationError( 'Date of government reply has to be past the date of the incident.' ) # Violations: Auto-add top-level entries when sub-cat is selected if not "AD" in self.violations: if any(True for x in self.violations if x in ["IC", "PC", "RT"]): self.violations.append("AD") if not "KA" in self.violations: if any(True for x in self.violations if x in ["KK", "K"]): self.violations.append("KA") if not "P" in self.violations: if any(True for x in self.violations if x in ["UT", "C"]): self.violations.append("P") if not "AD" in self.violations2: if any(True for x in self.violations2 if x in ["IC", "PC", "RT"]): self.violations2.append("AD") if not "KA" in self.violations2: if any(True for x in self.violations2 if x in ["KK", "K"]): self.violations2.append("KA") if not "P" in self.violations2: if any(True for x in self.violations2 if x in ["UT", "C"]): self.violations2.append("P") if not "AD" in self.violations3: if any(True for x in self.violations3 if x in ["IC", "PC", "RT"]): self.violations3.append("AD") if not "KA" in self.violations3: if any(True for x in self.violations3 if x in ["KK", "K"]): self.violations3.append("KA") if not "P" in self.violations3: if any(True for x in self.violations3 if x in ["UT", "C"]): self.violations3.append("P") if not "AD" in self.violations4: if any(True for x in self.violations4 if x in ["IC", "PC", "RT"]): self.violations4.append("AD") if not "KA" in self.violations4: if any(True for x in self.violations4 if x in ["KK", "K"]): self.violations4.append("KA") if not "P" in self.violations4: if any(True for x in self.violations4 if x in ["UT", "C"]): self.violations4.append("P") # Fill geolocation: self.get_coordinates() def save(self, *args, **kwargs): self.clean() super(Record, self).save(*args, **kwargs) # Call the "real" save() method. # Choices for select boxes GENDER_CHOICES = ((0, _("Male")), (1, _("Female")), (2, _("Trans/inter*")), (3, _("Gender unclear"))) ISSUE_CHOICES = ( ("?", _("N/A")), ("WR", _("Women's rights")), ("CRS", _("Children's rights")), ("IPR", _("Indigenous peoples' rights")), ("LGBTI", _("LGBTI issues")), ("MRR", _("Migrants'/refugees'/IDP's rights")), ("MR", _("Ethnic minorities' rights")), ("LR", _("Labour rights")), ("POV", _("Poverty/social welfare")), ("RTF", _("Right to food/water")), ("HI", _("Health issues")), ("RE", _("Right to education")), ("HRFE", _("Housing rights/forced evictions")), ("LNR", _("Land rights/environment")), ("CR", _("Cultural rights")), ("RF", _("Religious freedom")), ("PR", _("Prisoner's rights")), ("AT", _("Torture")), ("DP", _("Death penalty")), ("ED", _("Enforced disappearance")), ("H", _("Homocide")), ("PV", _("Police/military violence")), ("NSV", _("Non-state violence")), ("AC", _("Corruption")), ("DV", _("Democratic/voting rights")), ("JI", _("Judicial independence")), ("IF", _("Internet freedom")), ("HRE", _("Human rights education")), ("TJ", _("Transitional justice")), ("PA", _("Peace activism")), ("AR", _("Anti-racism")), ("RP", _("Right to privacy")), ) ACTIVITIES_CHOICES = ( ("?", _("N/A")), ("CSA", _("Civil society activist")), ("TUA", _("Trade union activist")), ("RA", _("Religious association")), ("PM", _("Politician/Party member")), ("CL", _("Community leader")), ("L", _("Lawyer/Judge/Attorney")), ("J", _("Journalist/Editor")), ("CA", _("Cyberactivist")), ("A", _("Artist/Writer")), ("S", _("Student")), ("T", _("Teacher/Professor/Scientist")), ("MP", _("Medical professional")), ("HW", _("Humanitarian worker")), ("V", _("Victim/witness of HR violations")), ("OP", _("Ombudsperson/Procuraduria/NHRI")), ("UN", _("UN official")), ("GAS", _("Government/Army/Security forces")), ("I", _("Investigation against officials")), ("PC", _("Participation in conference/meeting")), ("PP", _("Participation in public protest/rally")), ) COOPERATION_CHOICES = ( (0, _("Not mentioned")), (1, _("UN")), (2, _("INGO/other IO")), ) LOCATION_CHOICES = (("C", _("Capital")), ("T", _("City/Town")), ("R", _("Rural area")), ("A", _("Abroad")), ("?", _("Unknown"))) VIOLATION_FAMILY_CHOICES = ( (0, _("Only HRD")), (1, _("against relative")), (2, _("against both")), ) VIOLATIONS_CHOICES = ( ("?", _("N/A")), ("AD", _("Arrest/Detention")), ("IC", _("Incommunicado")), ("PC", _("Held in poor conditions")), ("RT", _("Risk of torture")), ("TI", _("Torture/Ill-treatment")), ("ED", _("Enforced disappearance")), ("KA", _("Physical attack")), ("KK", _("Killing attempt")), ("K", _("Killing")), ("DI", _("Kidnapping")), ("P", _("Trial")), ("UT", _("Unfair trial")), ("C", _("Conviction")), ("T", _("Threats")), ("S", _("Surveillance")), ("R", _("Office/home raided")), ("PD", _("Property stolen/confiscated/destroyed")), ("DC", _("Defamation campaign")), ("DP", _("Disciplinary proceedings")), ("B", _("Travel restrictions")), ("A", _("Access denied")), ("VD", _("Expulsion/Visa denied")), ("AH", _("Administrative harassment")), ("FI", _("Failure to intervene/protect")), ("CR", _("Citizenship revoked")), ) PERPETRATOR_CHOICES = ( ("U", _("Unknown")), ("P", _("Police/security forces")), ("CS", _("Public official/administration/judiciary")), ("A", _("Army")), ("AO", _("Armed opposition")), ("B", _("Business/landholder")), ("M", _("Mob")), ("PM", _("Paramilitary group")), ("PP", _("Private person")), ("RA", _("Religious authority")), ) INTERVENTION_CHOICES = ( ("?", _("N/A")), ("UA", _("UA")), ("JUA", _("JUA")), ("AL", _("AL")), ("JAL", _("JAL")), ("PR", _("PR")), ) JOINT_CHOICES = ( ("FrASSEM", _("FrASSEM")), ("FrEXPRESS", _("FrEXPRESS")), ("TORTURE", _("TORTURE")), ("WGAD", _("WGAD")), ("WGED", _("WGED")), ("SumEXECU", _("SumEXECU")), ("WOMEN", _("WOMEN")), ("FrRELIGION", _("FrRELIGION")), ("JUDGES", _("JUDGES")), ("INDIGENOUS", _("INDIGENOUS")), ("TERRORISM", _("TERRORISM")), ("BUSINESS", _("BUSINESS")), ("HEALTH", _("HEALTH")), ("ENVIR", _("ENVIR")), ("FOOD", _("FOOD")), ("CHILD", _("CHILD")), ("RACISM", _("RACISM")), ("HOUSING", _("HOUSING")), ("MINORITY", _("MINORITY")), ("EDUCATION", _("EDUCATION")), ("MIGRANTS", _("MIGRANTS")), ("WASTE", _("WASTE")), ("IDPs", _("IDPs")), ("WG_WOMEN", _("WG_WOMEN")), ("MERCENARIES", _("MERCENARIES")), ("TRUTH", _("TRUTH")), ("POVERTY", _("POVERTY")), ("CULTURE", _("CULTURE")), ("ELDERLY", _("ELDERLY")), ("SLAVERY", _("SLAVERY")), ("WATER", _("WATER")), ("AFRICAN", _("AFRICAN")), ("DISCAPA", _("DISCAPA")), ("SOLIDAR", _("SOLIDAR")), ("INTORDER", _("INT'ORDER")), ("TRAFFIC", _("TRAFFIC")), ("PRIVACY", _("PRIVACY")), ("DEBT", _("DEBT")), ("SOGI", _("SOGI")), ("specific", _("Country-specific")), ) CONCERN_CHOICES = ( ("CV", _("Concern over violation")), ("PV", _("Concern: Pattern of violation")), ("PM", _("Demand: Protection measures")), ("II", _("Demand: Independent investigation")), ("PI", _("Demand: Provide information")), ("RD", _("Demand: Release detainee")), ) GOV_REPLY_CHOICES = ( ("reject", _("Violation rejected")), ("incomp", _("Reponsive but incomplete")), ("immat", _("Immaterial response")), ("react", _("Steps taken to address")), ("transl", _("In translation")), ("na", _("File not available")), ) GOV_ACTION_CHOICES = ( ("protect", _("Protection measures granted")), ("release", _("Individual released early")), ("notrial", _("Individual released without trial")), ("improve", _("Improved prison conditions")), ("investigate", _("Investigation opened")), ("prosecuted", _("Perpetrator suspended/prosecuted")), ("issued", _("Travel documents issued")), ("other", _("Other")), ) SOURCES_CHOICES = ( ("NGO", _("INGO")), ("RNGO", _("RNGO")), ("LNGO", _("LNGO")), ("GOV", _("GOV")), ("IO", _("IO")), ("IND", _("Indiv.")), ) # Data model implementation person_id = models.CharField( max_length=13, verbose_name=_("Person ID"), unique=True, validators=[ int_list_validator(sep='-', message=None, code='invalid'), MinLengthValidator(13, message=None) ], help_text= _("Form YYYY-CCCC-PPP, where YYYY is the year of publication, CCCC is the paragraph number given in the report, and PPP the person number within the communication" )) ohchr_case = models.CharField(max_length=20, blank=True, verbose_name=_("OHCHR case no.")) country = CountryField(blank_label=_('(select country)'), verbose_name=_("Country")) date_intervention = models.DateField( verbose_name=_("Date of the intervention"), help_text=_("Format YYYY-MM-DD"), blank=True, null=True) type_intervention = models.CharField( max_length=3, choices=INTERVENTION_CHOICES, verbose_name=_("Type of intervention")) joint_with = SelectMultipleField( max_length=200, choices=JOINT_CHOICES, blank=True, verbose_name=_("Joint with"), help_text=_("Select multiple items with <i>Ctrl+Click</i>")) name = models.CharField(max_length=500, verbose_name=_("Name of HRD")) gender = models.IntegerField(choices=GENDER_CHOICES, verbose_name=_("Gender")) follow_up_case = models.BooleanField( default=False, verbose_name=_("Follow-up on UN case")) follow_ups = models.ManyToManyField('self', default=None, blank=True, verbose_name="Follow-up Person IDs") earlier_coms = models.CharField(blank=True, max_length=500, verbose_name=_("Date(s) of earlier coms")) regional_case = models.BooleanField( default=False, verbose_name=_("Regional mechanism case")) issue_area = SelectMultipleField( max_length=20, choices=ISSUE_CHOICES, max_choices=3, default="?", verbose_name=_("Issue area"), help_text=_("Select maximum 3 items with <i>Ctrl+Click</i>")) relevant_activities = SelectMultipleField( max_length=15, choices=ACTIVITIES_CHOICES, max_choices=3, default="?", verbose_name=_("Relevant activities"), help_text=_("Select maximum 3 items with <i>Ctrl+Click</i>")) affiliation = models.CharField(blank=True, max_length=500, verbose_name=_("Affiliation")) further_info = models.TextField( blank=True, verbose_name=_("Further information"), help_text= _("Name of NGO or party, title of conference, object of investigation etc." )) foreign_national = models.BooleanField(default=False, verbose_name=_("Foreign national")) international_cooperation = models.IntegerField( choices=COOPERATION_CHOICES, default=0, verbose_name=_("International cooperation")) location = models.CharField(max_length=1, choices=LOCATION_CHOICES, default="?", verbose_name=_("Location")) name_area = models.CharField(max_length=500, blank=True, verbose_name=_("Name of City / Area")) violation_family = models.IntegerField( choices=VIOLATION_FAMILY_CHOICES, default=0, verbose_name=_("Violation against HRD or family member?")) violation_family_who = models.CharField( max_length=500, blank=True, verbose_name=_("Concerned family member")) violations = SelectMultipleField( max_length=50, choices=VIOLATIONS_CHOICES, default="?", verbose_name=_("Violation(s)"), help_text=_("Select multiple items with <i>Ctrl+Click</i>")) perpetrator = SelectMultipleField( max_length=10, choices=PERPETRATOR_CHOICES, default="U", verbose_name=_("Alleged perpetrator"), help_text=_("Select multiple items with <i>Ctrl+Click</i>")) violations2 = SelectMultipleField( max_length=50, choices=VIOLATIONS_CHOICES, verbose_name=_("Violation(s) #2"), help_text=_("Select multiple items with <i>Ctrl+Click</i>"), blank=True) perpetrator2 = SelectMultipleField( max_length=10, choices=PERPETRATOR_CHOICES, verbose_name=_("Alleged perpetrator #2"), help_text=_("Select multiple items with <i>Ctrl+Click</i>"), blank=True) violations3 = SelectMultipleField( max_length=50, choices=VIOLATIONS_CHOICES, verbose_name=_("Violation(s) #3"), help_text=_("Select multiple items with <i>Ctrl+Click</i>"), blank=True) perpetrator3 = SelectMultipleField( max_length=10, choices=PERPETRATOR_CHOICES, verbose_name=_("Alleged perpetrator #3"), help_text=_("Select multiple items with <i>Ctrl+Click</i>"), blank=True) violations4 = SelectMultipleField( max_length=50, choices=VIOLATIONS_CHOICES, verbose_name=_("Violation(s) #4"), help_text=_("Select multiple items with <i>Ctrl+Click</i>"), blank=True) perpetrator4 = SelectMultipleField( max_length=10, choices=PERPETRATOR_CHOICES, verbose_name=_("Alleged perpetrator #4"), help_text=_("Select multiple items with <i>Ctrl+Click</i>"), blank=True) date_incident = models.DateField( null=True, blank=True, verbose_name=_("Date of the latest incident"), help_text=_("Format YYYY-MM-DD")) date_incident_unspecific = models.CharField( max_length=500, blank=True, verbose_name=_("If unspecific")) concern_expressed = models.CharField( max_length=2, choices=CONCERN_CHOICES, verbose_name=_("Concern/demand expressed in intervention"), blank=True) is_released = models.BooleanField(default=False, verbose_name=_("If arrested: released?")) ########################## date_govreply = models.DateField( null=True, blank=True, verbose_name=_("Date of government reply"), help_text=_('Format YYYY-MM-DD, leave empty for "No response"')) date_govreply_further = models.CharField( max_length=500, blank=True, verbose_name=_("Date(s) of further replies")) govreply_content = models.CharField( max_length=6, choices=GOV_REPLY_CHOICES, verbose_name=_("Content of government reply"), help_text=_("According to rating criteria by Piccone (2012)"), blank=True) date_govaction = models.DateField( null=True, blank=True, verbose_name=_("Date of action according to reply"), help_text=_("Format YYYY-MM-DD")) govreply_action = models.CharField( max_length=11, choices=GOV_ACTION_CHOICES, verbose_name=_("Action taken according to reply"), blank=True) ########################## further_comments = models.TextField( blank=True, verbose_name=_("Further comments"), help_text=_( "Observations that might be relevant but don't fit elsewhere")) feedback = models.TextField( blank=True, verbose_name=_("Feedback"), help_text=_("Direct feedback on the coding of this particular case")) upload = models.FileField(upload_to=update_filename, null=True, blank=True, verbose_name=_("Uploads")) analyst = models.ForeignKey( User, blank=True, null=True, verbose_name=_("Analyst"), help_text=_("User responsible for this record")) is_final = models.BooleanField(default=False, verbose_name=_("Final")) business_case = models.BooleanField( default=False, verbose_name=_("Business-related case")) business_company = models.CharField(blank=True, max_length=500, verbose_name=_("Name of company")) sources_number = models.CharField(blank=True, max_length=50, verbose_name=_("Number of sources")) sources_type = SelectMultipleField( max_length=50, choices=SOURCES_CHOICES, verbose_name=_("Type of sources"), help_text=_("Select multiple items with <i>Ctrl+Click</i>"), blank=True) complaint_sent = models.DateField(null=True, blank=True, verbose_name=_("Complaint sent on"), help_text=_("Format YYYY-MM-DD")) complaint_received = models.DateField( null=True, blank=True, verbose_name=_("Complaint received on"), help_text=_("Format YYYY-MM-DD")) coords = PointField(blank=True, null=True, editable=False, verbose_name=_("Coordinates")) def has_related_object(self): return hasattr(self, 'followup') def get_geoname(self): return "%s" % ( self.country.name ) if not self.name_area or self.location == 'A' else "%s, %s" % ( self.name_area, self.country.name) def get_coordinates(self): geolocator = Nominatim() try: loc = geolocator.geocode(self.get_geoname()) tmp = PointField() tmp = { "type": "Point", "coordinates": [float(loc.longitude), float(loc.latitude)] } #if tmp != self.coords: #print "Updated record %s: %s -> %s" % (self.person_id, "none" if not self.coords else self.coords['coordinates'], tmp['coordinates']) self.coords = tmp #print "Located record %s (%s)" % (self.person_id, unicode(self.name)) + " with: " + unicode(self.get_geoname()) + " " + str(loc.longitude) + " " + str(loc.latitude) except AttributeError: #print "Could not locate record %s (%s)" % (self.person_id, unicode(self.name)) + " with: " + unicode(self.get_geoname()) pass except GeocoderServiceError: #print "Geocoder service error on record %s (%s)" % (self.person_id, unicode(self.name)) pass # Produce list with field items: def get_field_list(self): thisrow = list() for field in self._meta.get_fields(): try: if isinstance(field, models.ManyToManyField): thisrow.append("\"" + force_bytes( [p.person_id for p in getattr(self, field.name).all()]) + "\"") elif isinstance(field, CountryField): thisrow.append( "\"" + force_bytes(getattr(self, field.name).alpha3) + "\"") else: thisrow.append("\"" + force_bytes(getattr(self, field.name)) + "\"") except: thisrow.append("\"\"") return thisrow def as_geojson_dict(self): """ Method to return each feature in the DB as a geojson object. """ if self.coords is not None: place = self.get_geoname() as_dict = { "type": "Feature", "geometry": self.coords, "properties": { "date": dateformat.format(self.date_intervention, 'F j, Y') if self.date_intervention else "unknown", "type": self.type_intervention, "location": place, "id": self.id } } else: as_dict = {} return as_dict
class Property(models.Model): """ Property where you find one or more trees for harvesting. """ is_active = models.BooleanField( verbose_name=_("Is active"), help_text=_("This property exists and may be able to host a pick"), default=True) authorized = models.NullBooleanField( verbose_name=_("Authorized for this season"), help_text= _("Harvest in this property has been authorized for the current season by its owner" ), default=None) pending = models.BooleanField( verbose_name=_("Pending"), help_text= _("This property was created through a public form and needs to be validated by an administrator" ), default=True) pending_contact_name = models.CharField( verbose_name=_("Contact name"), help_text=_("Name of the person to be contacted for confirmation"), max_length=50) pending_contact_phone = models.CharField( verbose_name=_("Contact phone number"), help_text=_("Phone number to be used for confirmation"), max_length=50) pending_contact_email = models.EmailField( verbose_name=_("Contact email"), help_text=_("Email address to be used for confirmation"), null=True, blank=True, ) pending_newsletter = models.BooleanField( verbose_name=_("Newsletter subscription"), default=False) pending_recurring = models.BooleanField( verbose_name=_("Recurring property signup"), default=False) geom = PointField(null=True, blank=True) owner = models.ForeignKey('member.Actor', null=True, blank=True, verbose_name=_("Owner")) # FIXME: add help_text in forms.py trees = models.ManyToManyField( 'TreeType', verbose_name=_("Fruit tree/vine type(s)"), help_text= _('Select multiple fruit types if applicable. Unknown fruit type or colour can be mentioned in the additional comments at the bottom.' ), ) trees_location = models.CharField(verbose_name=_("Trees location"), help_text=_("Front yard or backyard?"), null=True, blank=True, max_length=200) trees_accessibility = models.CharField( verbose_name=_("Trees accessibility"), help_text=_("Any info on how to access the tree (eg. key, gate etc)"), null=True, blank=True, max_length=200) avg_nb_required_pickers = models.PositiveIntegerField( verbose_name=_("Required pickers on average"), null=True, default=1) public_access = models.BooleanField( verbose_name=_("Publicly accessible"), default=False, ) neighbor_access = models.BooleanField( verbose_name=_("Access to neighboring terrain if needed"), default=False, ) compost_bin = models.BooleanField( verbose_name=_("Compost bin closeby"), default=False, ) ladder_available = models.BooleanField( verbose_name=_("There is a ladder available in the property"), default=False, ) ladder_available_for_outside_picks = models.BooleanField( verbose_name= _("A ladder is available in the property and can be used for nearby picks" ), default=False, ) harvest_every_year = models.BooleanField( verbose_name=_("Produces fruits every year"), default=False, ) number_of_trees = models.PositiveIntegerField( verbose_name=_("Total number of trees/vines on this property"), blank=True, null=True) approximative_maturity_date = models.DateField( verbose_name=_("Approximative maturity date"), help_text=_("When is the tree commonly ready to be harvested?"), blank=True, null=True) fruits_height = models.PositiveIntegerField( verbose_name=_("Height of lowest fruits"), blank=True, null=True) street_number = models.CharField(verbose_name=_("Number"), max_length=10, null=True, blank=True) street = models.CharField(verbose_name=_("Street"), max_length=50, null=True, blank=True) complement = models.CharField(verbose_name=_("Complement"), max_length=150, null=True, blank=True) postal_code = models.CharField(verbose_name=_("Postal code"), max_length=10, null=True, blank=True) publishable_location = models.CharField( verbose_name=_("Publishable location"), help_text= _("Aproximative location to be used in public communications (not the actual address)" ), max_length=50, null=True, blank=True) neighborhood = models.ForeignKey('member.Neighborhood', verbose_name=_("Neighborhood"), null=True) city = models.ForeignKey('member.City', verbose_name=_("City"), null=True, default=1) state = models.ForeignKey('member.State', verbose_name=_("Province"), null=True, default=1) country = models.ForeignKey('member.Country', verbose_name=_("Country"), null=True, default=1) longitude = models.FloatField(verbose_name=_("Longitude"), null=True, blank=True) latitude = models.FloatField(verbose_name=_("Latitude"), null=True, blank=True) additional_info = models.CharField( verbose_name=_("Additional information"), help_text=_("Any additional information that we should be aware of"), max_length=1000, null=True, blank=True) changed_by = models.ForeignKey('member.AuthUser', null=True, blank=True) class Meta: verbose_name = _("property") verbose_name_plural = _("properties") def __str__(self): if self.street_number: return u"%s at %s %s" % \ (self.owner, self.street_number, self.street) else: return u"%s at %s" % \ (self.owner, self.street) @property def short_address(self): if self.street_number and self.street and self.complement: return "%s %s, %s" % (self.street_number, self.street, self.complement) elif self.street and self.street_number: return "%s %s" % (self.street_number, self.street) elif self.street and self.complement: return "%s, %s" % (self.street, self.complement) else: return self.street def get_absolute_url(self): return reverse_lazy('harvest:property_detail', args=[self.id]) def get_harvests(self): harvests_list = Harvest.objects.filter( property=self).order_by('-start_date') return harvests_list def get_last_succeeded_harvest(self): last_harvest = Harvest.objects.filter(property=self).filter( status="Succeeded").order_by('-start_date') if last_harvest: return last_harvest[0] @property def get_owner_name(self): return self.owner.__str__()
class Event(models.Model): """Model to represent Event objects""" initiative = models.ForeignKey( Initiative, verbose_name=_("Iniciativa que organiza la actividad"), blank=True, null=True, help_text=_('¿Qué iniciativa organiza el evento?')) title = models.CharField( _('Título del evento'), max_length=200, blank=False, null=True, help_text=_('¿Cuál es el título del evento que quieres organiza?')) featured = models.BooleanField( _('Destacado'), blank=True, default=False, help_text=_('Indica si es un evento destacado')) description = models.TextField(_('Describe el evento'), blank=False, null=True, help_text=_('Describe el evento.')) image = models.ImageField( _("Imagen"), blank=True, validators=[validate_image_size, validate_image_type], upload_to=events_images_path, help_text= _("Sube una imagen representativa del evento haciendo click en la imagen inferior. " "La imagen ha de tener ancho mínimo de 300 píxeles y máximo de 1920, y altura mínima " "de 300 píxeles y máxima de 1280. Formatos permitidos: PNG, JPG, JPEG." )) image_medium = ImageSpecField( source="image", processors=[processors.ResizeToFill(600, 300)], format='JPEG', options={'quality': 90}) video = models.CharField( _('Video'), max_length=200, blank=True, null=True, help_text=_('Inserta la url de un video de Youtube o Vimeo')) website = models.URLField( _('Enlace'), blank=True, null=True, help_text=_( 'Especifica opcionalmente un enlace para conocer mejor el evento.') ) topic = models.CharField(_('Temática del evento'), blank=False, null=False, default='DC', max_length=2, choices=categories.TOPICS, help_text=_('El tema de la actividad')) category = models.CharField( _('Tipo de actividad'), blank=False, null=False, default='AU', max_length=2, choices=categories.ACTIVITIES, help_text=_('El tipo de actividad que quieres organizar')) agent = models.CharField( _('tipo de agente'), blank=False, null=False, default='IM', max_length=2, choices=categories.AGENTS, help_text=_('El tipo de agente involucrado en la actividad')) date = models.DateField( _('Fecha del evento'), help_text=_('Indica qué día se celebra o empieza el evento')) time = models.TimeField(_('Hora del evento'), help_text=_('¿A qué hora se celebra el evento?')) periodicity = models.CharField( _('Periodicidad'), max_length=200, blank=True, null=True, help_text= _('Especifica, en ese caso, la periodicidad del evento. Puedes indicar la fecha de fin en el siguiente campo' )) expiration = models.DateField( _('Fecha de fin'), blank=True, null=True, help_text= _('Indica opcionalmente en eventos de varios dias la fecha en que acaba el evento.' )) city = models.ForeignKey( City, verbose_name=_('Ciudad'), blank=False, null=True, on_delete=models.SET_NULL, help_text= _('Ciudad donde se encuentra la iniciativa. Si no la encuentras en la lista puedes añadir una nueva.' )) address = models.CharField( _('Dirección'), max_length=200, blank=False, null=True, help_text= _('Dirección de la iniciativa. No es necesario que vuelvas a introducir la ciudad de la iniciativa.' )) position = PointField( _("Ubicación"), blank=False, null=True, help_text= _("Añade la ubicación de la actividad. Si lo dejas en blanco se usará la ubicación de la iniciativa asociada." )) facebook_id = models.CharField(max_length=128, blank=True, null=True) google_id = models.CharField(max_length=128, blank=True, null=True) slug = models.SlugField(editable=False, blank=True) creation_date = models.DateField(editable=False, default=timezone.now) class Meta: verbose_name = _('Actividad') verbose_name_plural = _('Actividades') def __str__(self): """String representation of this model objects.""" return self.title or '---' def save(self, *args, **kwargs): """Populate automatically 'slug' field""" self.slug = slugify(self.title) # Notify by mail, only when creating new content if not self.id: send_mail( 'Creado el evento \"' + self.title + "\"", 'Creado el ' + self.creation_date.strftime("%d/%b/%Y") + ' por "' + self.initiative.name + '" (' + self.initiative.email + ')\n---\n' + self.title + ':\n' + self.description + '\n---\n' + 'Ciudad: ' + self.city.name, 'civics.cc <*****@*****.**>', settings.NOTIFICATIONS_EMAILS, fail_silently=False, ) super(Event, self).save(*args, **kwargs) def edit_permissions(self, user): """Returns users allowed to edit an instance of this model.""" if user.is_staff or (self.initiative and self.initiative.user and self.initiative.user == user): return True return False
class Tree(models.Model): EMERGENTE = 'Emergente' DOMINANTE = 'Dominante' CODOMINANTE = 'Codominante' INTERMEDIA = 'Intermedia' INFERIOR_SUPRIMIDO = 'Inferior suprimido' INFERIOR_SUMERGIDO = 'Inferior sumergido' SOCIOLOGICAL_CLASSIFICATION_CHOICES = [ (EMERGENTE, 'Emergente'), (DOMINANTE, 'Dominante'), (CODOMINANTE, 'Codominante'), (INTERMEDIA, 'Intermedia'), (INFERIOR_SUPRIMIDO, 'Inferior Suprimido'), (INFERIOR_SUMERGIDO, 'Supeior Sumergido'), ] BUENO = 'Bueno' REGULAR = 'Regular' MALO = 'Malo' MUERTO = 'Muerto' PHYTOSANITARY_STATUS_CHOICES = [ (BUENO, 'Bueno'), (REGULAR, 'Regular'), (MALO, 'Malo'), (MUERTO, 'Muerto') ] field = models.ForeignKey('FieldWork', on_delete=models.CASCADE) tree_id = models.IntegerField(verbose_name='ID Árbol') # todo ID Árbol: N colecta nombre subparcela (SY) o 2 numeros y cuatro letras o tres numeros y cuatro letras specie = models.CharField(verbose_name='Nombre especie', max_length=100) dap = models.FloatField(verbose_name='DAP', help_text='cm') dab = models.FloatField(verbose_name='DAB', help_text='cm') tree_height = models.FloatField(verbose_name='Altura del árbol', help_text='m', validators = [tree_height_validation]) latitude = models.FloatField(verbose_name='latitud', validators=[validate_lat], help_text="informar en formato graus decimais WGS84") longitude = models.FloatField(verbose_name='longitud', validators=[validate_lon]) picture = models.ForeignKey(Pictures, on_delete=models.CASCADE, blank=True, null = True) obs = models.TextField(verbose_name="Observaciones", blank=True) phytosanitary_status = models.CharField(max_length=100, choices=PHYTOSANITARY_STATUS_CHOICES, default=BUENO) sociological_classification = models.CharField(verbose_name='clasificación sociologica', max_length=100, choices=SOCIOLOGICAL_CLASSIFICATION_CHOICES, default=EMERGENTE) geom = PointField(blank=True) class Meta: verbose_name = 'Árbol' verbose_name_plural = 'Árboles' def __str__(self): return f'{self.specie} {self.field.date}' def get_absolute_url(self): return reverse_lazy('imibio_tree_ecological_data:detail', kwargs={'pk': self.pk}) @property def popup_content(self): # todo Me parece que lo importante es poner alguna foto popup = "<strong><span>Nombre científico: </span>{}</strong></p>".format( self.specie) popup += "<span>Condición fitosanitario: </span>{}<br>".format( self.phytosanitary_status) popup += "<span>Altura: </span>{}<br>".format( self.tree_height) popup += f"<span><a href={self.get_absolute_url()}>Detalles de la occurrencia</a></strong><br>" return popup
class LugarVotacion(models.Model): circuito = models.ForeignKey(Circuito, related_name='escuelas', on_delete=models.CASCADE) nombre = models.CharField(max_length=100) direccion = models.CharField(max_length=100) barrio = models.CharField(max_length=100, blank=True) ciudad = models.CharField(max_length=100, blank=True) calidad = models.CharField(max_length=20, help_text='calidad de la geolocalizacion', editable=False, blank=True) electores = models.PositiveIntegerField(null=True, blank=True) geom = PointField(null=True) estado_geolocalizacion = models.PositiveIntegerField( default=0, help_text='Indicador (0-10) de que confianza hay en la geolozalización' ) # denormalizacion para hacer queries más simples latitud = models.FloatField(null=True, editable=False) longitud = models.FloatField(null=True, editable=False) class Meta: verbose_name = 'Lugar de votación' verbose_name_plural = "Lugares de votación" def save(self, *args, **kwargs): if self.geom: self.longitud, self.latitud = self.geom['coordinates'] else: self.longitud, self.latitud = None, None super().save(*args, **kwargs) @property def coordenadas(self): return f'{self.latitud},{self.longitud}' @property def direccion_completa(self): return f'{self.direccion} {self.barrio} {self.ciudad}' @property def mesas_desde_hasta(self): qs = self.mesas qs = qs.values_list('numero', flat=True).order_by('numero') inicio, fin = qs.first(), qs.last() if inicio == fin: return inicio return f'{inicio} - {fin}' def mesas(self, eleccion): return Mesa.objects.filter(lugar_votacion=self, eleccion=eleccion) @property def mesas_actuales(self): return self.mesas.filter(eleccion=Eleccion.actual()) @property def color(self): if VotoMesaReportado.objects.filter( mesa__lugar_votacion=self).exists(): return 'green' return 'orange' @property def seccion(self): return str(self.circuito.seccion) def __str__(self): return f"{self.nombre} - {self.circuito}"
class Barangay(models.Model): name = models.CharField(max_length=20) geom = PointField() def __str__(self): return self.name
class Event(models.Model): """Reference event model.""" title = models.CharField(verbose_name=_("title"), max_length=400) description = models.TextField(verbose_name=_("description")) read_time = models.IntegerField(default=0, verbose_name=_("read time")) slug = models.SlugField(verbose_name=_("slug"), unique=True, blank=True) event_date = models.DateTimeField(verbose_name=_("event date")) total_guest = models.PositiveIntegerField(verbose_name=_("total of guest"), default=1) hosted_by = models.ForeignKey( settings.AUTH_USER_MODEL, verbose_name=_("hosted by"), on_delete=models.CASCADE, related_name="events", db_index=True, ) cover = models.ImageField(verbose_name=_("cover"), blank=True, null=True, upload_to=event_upload_to) tags = models.ManyToManyField(to=Tag, verbose_name=_("tags"), related_name="events", blank=True) organizers = models.ManyToManyField( to=settings.AUTH_USER_MODEL, verbose_name=_("organizers"), related_name="events_organizers", blank=True, ) created_at = models.DateTimeField(verbose_name=_("created at"), auto_now_add=True) updated_at = models.DateTimeField(verbose_name=_("updated at"), auto_now=True) geom = PointField(verbose_name=_("geo location")) class Meta: """Meta data.""" verbose_name = _("event") verbose_name_plural = _("events") def __str__(self: "Event") -> str: """It return readable name for the model.""" return f"{self.title}" def total_attendees(self: "Event") -> int: """Getting total of attendees for the event.""" return self.attendees.count() def available_place(self: "Event") -> int: """Getting total of available place for the event.""" return self.total_guest - self.attendees.count() def total_attended(self: "Event") -> int: """Getting total of people who actual attended for the event.""" return self.attendees.filter(has_attended=True).count() def total_not_attended(self: "Event") -> int: """Getting total of people who didn't attended for the event.""" return self.attendees.filter(has_attended=False).count() def total_sessions(self: "Event") -> int: """Getting total of sessions in event.""" return self.sessions.count() def total_draft_sessions(self: "Event") -> int: """Getting total of draft sessions in event.""" return self.sessions.filter(status="Draft").count() def total_accepted_sessions(self: "Event") -> int: """Getting total of accepted sessions in event.""" return self.sessions.filter(status="Accepted").count() def total_denied_sessions(self: "Event") -> int: """Getting total of denied sessions in event.""" return self.sessions.filter(status="Denied").count() def total_talk(self: "Event") -> int: """Getting total of talk in event.""" return self.sessions.filter(session_type="Talk", status="Accepted").count() def total_lighting_talk(self: "Event") -> int: """Getting total of lighting talk in event.""" return self.sessions.filter(session_type="Lighting Talk", status="Accepted").count() def total_workshop(self: "Event") -> int: """Getting total of workshop in event.""" return self.sessions.filter(session_type="WorkShop", status="Accepted").count() total_sessions.short_description = _("Sessions") total_draft_sessions.short_description = _("Draft Sessions") total_accepted_sessions.short_description = _("Accepted Sessions") total_denied_sessions.short_description = _("Denied Sessions") total_talk.short_description = _("Talk") total_lighting_talk.short_description = _("Lighting Talk") total_workshop.short_description = _("Workshop") total_attendees.short_description = _("Attendees") total_attended.short_description = _("Has Attended") total_not_attended.short_description = _("Has Not Attended") available_place.short_description = _("Available Place")
class Agency(models.Model, RequestHelper): """An agency for a particular jurisdiction that has at least one agency type""" name = models.CharField(max_length=255) slug = models.SlugField(max_length=255) jurisdiction = models.ForeignKey(Jurisdiction, related_name='agencies') types = models.ManyToManyField(AgencyType, blank=True) status = models.CharField(choices=( ('pending', 'Pending'), ('approved', 'Approved'), ('rejected', 'Rejected'), ), max_length=8, default='pending') user = models.ForeignKey(User, null=True, blank=True) appeal_agency = models.ForeignKey('self', null=True, blank=True) can_email_appeals = models.BooleanField(default=False) payable_to = models.ForeignKey('self', related_name='receivable', null=True, blank=True) image = ThumbnailerImageField( upload_to='agency_images', blank=True, null=True, resize_source={'size': (900, 600), 'crop': 'smart'} ) image_attr_line = models.CharField(blank=True, max_length=255, help_text='May use html') public_notes = models.TextField(blank=True, help_text='May use html') stale = models.BooleanField(default=False) manual_stale = models.BooleanField(default=False, help_text='For marking an agency stale by hand.') address = models.TextField(blank=True) location = PointField(blank=True) email = models.EmailField(blank=True) other_emails = fields.EmailsListField(blank=True, max_length=255) contact_salutation = models.CharField(blank=True, max_length=30) contact_first_name = models.CharField(blank=True, max_length=100) contact_last_name = models.CharField(blank=True, max_length=100) contact_title = models.CharField(blank=True, max_length=255) url = models.URLField(blank=True, verbose_name='FOIA Web Page', help_text='Begin with http://') phone = models.CharField(blank=True, max_length=30) fax = models.CharField(blank=True, max_length=30) notes = models.TextField(blank=True) aliases = models.TextField(blank=True) parent = models.ForeignKey('self', null=True, blank=True, related_name='children') website = models.CharField(max_length=255, blank=True) twitter = models.CharField(max_length=255, blank=True) twitter_handles = models.TextField(blank=True) foia_logs = models.URLField(blank=True, verbose_name='FOIA Logs', help_text='Begin with http://') foia_guide = models.URLField(blank=True, verbose_name='FOIA Processing Guide', help_text='Begin with http://') exempt = models.BooleanField(default=False) requires_proxy = models.BooleanField(default=False) objects = AgencyQuerySet.as_manager() def __unicode__(self): return self.name def get_absolute_url(self): """The url for this object""" return host_reverse( 'agency-detail', host='default', kwargs={ 'jurisdiction': self.jurisdiction.slug, 'jidx': self.jurisdiction.pk, 'slug': self.slug, 'idx': self.pk, }) def save(self, *args, **kwargs): """Save the agency""" self.email = self.email.strip() self.slug = slugify(self.slug) self.name = self.name.strip() super(Agency, self).save(*args, **kwargs) def normalize_fax(self): """Return a fax number suitable for use in a faxaway email address""" fax = ''.join(c for c in self.fax if c.isdigit()) if len(fax) == 10: return '1' + fax if len(fax) == 11 and fax[0] == '1': return fax return None def get_email(self): """Returns an email address to send to""" if self.email: return self.email elif self.normalize_fax(): return '*****@*****.**' % self.normalize_fax() else: return '' def get_other_emails(self): """Returns other emails as a list""" return fields.email_separator_re.split(self.other_emails) def link_display(self): """Returns link if approved""" if self.status == 'approved': return mark_safe('<a href="%s">%s</a>' % (self.get_absolute_url(), self.name)) else: return self.name def is_stale(self): """Should this agency be marked as stale? If the latest response to any open request is greater than STALE_DURATION days ago, or if no responses to any open request, if the oldest open request was sent greater than STALE_DURATION days ago. If no open requests, do not mark as stale.""" # check if agency is manually marked as stale if self.manual_stale: return True # find any open requests, if none, not stale foias = self.foiarequest_set.get_open().order_by('date_submitted') if not foias: return False # find the latest response to an open request latest_responses = [] for foia in foias: response = foia.latest_response() if response: latest_responses.append(response) if latest_responses: return min(latest_responses) >= STALE_DURATION # no response to open requests, use oldest open request submit date return (date.today() - foias[0].date_submitted).days >= STALE_DURATION def mark_stale(self, manual=False): """Mark this agency as stale and create a StaleAgencyTask if one doesn't already exist.""" self.stale = True self.manual_stale = manual self.save() try: task, created = StaleAgencyTask.objects.get_or_create(resolved=False, agency=self) if created: logger.info('Created new StaleAgencyTask <%d> for Agency <%d>', task.pk, self.pk) except MultipleObjectsReturned as exception: # If there are multiple StaleAgencyTasks returned, just return the first one. # We only want this method to return a single task. # Also, log the exception as a warning. task = StaleAgencyTask.objects.filter(resolved=False, agency=self).first() logger.warning(exception) return task def unmark_stale(self): """Unmark this agency as stale and resolve all of its StaleAgencyTasks.""" self.stale = False self.manual_stale = False self.save() def count_thanks(self): """Count how many thanks this agency has received""" return (self.foiarequest_set .filter(communications__thanks=True) .distinct() .count()) def get_requests(self): """Just returns the foiareqest_set value. Used for compatability with RequestHeper mixin""" return self.foiarequest_set class Meta: # pylint: disable=too-few-public-methods verbose_name_plural = 'agencies'
class LugarVotacion(models.Model): """ Define el lugar de votación (escuela) que pertenece a un circuito y contiene mesas. Tiene un representación geoespacial (point). Sección -> Circuito -> **Lugar de votación** -> Mesa """ circuito = models.ForeignKey(Circuito, related_name='escuelas', on_delete=models.CASCADE) nombre = models.CharField(max_length=100) direccion = models.CharField(max_length=100) barrio = models.CharField(max_length=100, blank=True) ciudad = models.CharField(max_length=100, blank=True) # electores es una denormalización. debe coincidir con la sumatoria de # los electores de cada mesa de la escuela electores = models.PositiveIntegerField(null=True, blank=True) geom = PointField(null=True) # A veces, al importar datos, se realizan distintas iteraciones para geolocalizar # escuelas. Estos campos sirven para cuantificar la calidad y poder filtrar para # mejorar los valores de menor confianza estado_geolocalizacion = models.PositiveIntegerField( default=0, help_text='Indicador (0-10) de que confianza hay en la geolozalización' ) calidad = models.CharField(max_length=20, help_text='calidad de la geolocalizacion', editable=False, blank=True) # denormalizacion para hacer queries más simples # se sincronizan con ``geom`` en el método save() latitud = models.FloatField(null=True, editable=False) longitud = models.FloatField(null=True, editable=False) class Meta: verbose_name = 'Lugar de votación' verbose_name_plural = "Lugares de votación" def save(self, *args, **kwargs): if self.geom: self.longitud, self.latitud = self.geom['coordinates'] else: self.longitud, self.latitud = None, None super().save(*args, **kwargs) @property def coordenadas(self): return f'{self.latitud},{self.longitud}' @property def direccion_completa(self): return f'{self.direccion} {self.barrio} {self.ciudad}' @property def mesas_desde_hasta(self): qs = self.mesas qs = qs.values_list('numero', flat=True).order_by('numero') inicio, fin = qs.first(), qs.last() if inicio == fin: return inicio return f'{inicio} - {fin}' def mesas(self, categoria): """ Devuelve las mesas asociadas a este lugar de votación para una categoría dada """ return Mesa.objects.filter(lugar_votacion=self, categoria=categoria) @property def mesas_actuales(self): return self.mesas.filter(categoria=Categoria.actual()) @property def color(self): if VotoMesaReportado.objects.filter( mesa__lugar_votacion=self).exists(): return 'green' return 'orange' @property def seccion(self): return str(self.circuito.seccion) def __str__(self): return f"{self.nombre} - {self.circuito}"
class ImibioOccurrence(models.Model): #author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) gbifID = models.BigIntegerField(blank=True, null=True) abstract = models.TextField(blank=True, null=True) accessRights = models.TextField(blank=True, null=True) accrualMethod = models.TextField(blank=True, null=True) accrualPeriodicity = models.TextField(blank=True, null=True) accrualPolicy = models.TextField(blank=True, null=True) alternative = models.TextField(blank=True, null=True) audience = models.TextField(blank=True, null=True) available = models.TextField(blank=True, null=True) bibliographicCitation = models.TextField(blank=True, null=True) conformsTo = models.TextField(blank=True, null=True) contributor = models.TextField(blank=True, null=True) coverage = models.TextField(blank=True, null=True) created = models.TextField(blank=True, null=True) creator = models.TextField(blank=True, null=True) date = models.TextField(blank=True, null=True) dateAccepted = models.TextField(blank=True, null=True) dateCopyrighted = models.TextField(blank=True, null=True) dateSubmitted = models.TextField(blank=True, null=True) description = models.TextField(blank=True, null=True) educationLevel = models.TextField(blank=True, null=True) extent = models.TextField(blank=True, null=True) format = models.TextField(blank=True, null=True) hasFormat = models.TextField(blank=True, null=True) hasPart = models.TextField(blank=True, null=True) hasVersion = models.TextField(blank=True, null=True) identifier = models.TextField(blank=True, null=True) instructionalMethod = models.TextField(blank=True, null=True) isFormatOf = models.TextField(blank=True, null=True) isPartOf = models.TextField(blank=True, null=True) isReferencedBy = models.TextField(blank=True, null=True) isReplacedBy = models.TextField(blank=True, null=True) isRequiredBy = models.TextField(blank=True, null=True) isVersionOf = models.TextField(blank=True, null=True) issued = models.TextField(blank=True, null=True) language = models.TextField(blank=True, null=True) license = models.TextField(blank=True, null=True) mediator = models.TextField(blank=True, null=True) medium = models.TextField(blank=True, null=True) modified = models.TextField(blank=True, null=True) provenance = models.TextField(blank=True, null=True) publisher = models.TextField(blank=True, null=True) references = models.TextField(blank=True, null=True) relation = models.TextField(blank=True, null=True) replaces = models.TextField(blank=True, null=True) requires = models.TextField(blank=True, null=True) rights = models.TextField(blank=True, null=True) rightsHolder = models.TextField(blank=True, null=True) source = models.TextField(blank=True, null=True) spatial = models.TextField(blank=True, null=True) subject = models.TextField(blank=True, null=True) tableOfContents = models.TextField(blank=True, null=True) temporal = models.TextField(blank=True, null=True) title = models.TextField(blank=True, null=True) type = models.TextField(blank=True, null=True) valid = models.TextField(blank=True, null=True) institutionID = models.TextField(blank=True, null=True) collectionID = models.TextField(blank=True, null=True) datasetID = models.TextField(blank=True, null=True) institutionCode = models.TextField() collectionCode = models.TextField() datasetName = models.TextField(blank=True, null=True) ownerInstitutionCode = models.TextField(blank=True, null=True) basisOfRecord = models.TextField() informationWithheld = models.TextField(blank=True, null=True) dataGeneralizations = models.TextField(blank=True, null=True) dynamicProperties = models.TextField(blank=True, null=True) occurrenceID = models.TextField(blank=True, null=True) catalogNumber = models.TextField() recordNumber = models.TextField(blank=True, null=True) recordedBy = models.TextField(blank=True, null=True) individualCount = models.TextField(blank=True, null=True) organismQuantity = models.TextField(blank=True, null=True) organismQuantityType = models.TextField(blank=True, null=True) sex = models.TextField(blank=True, null=True) lifeStage = models.TextField(blank=True, null=True) reproductiveCondition = models.TextField(blank=True, null=True) behavior = models.TextField(blank=True, null=True) establishmentMeans = models.TextField(blank=True, null=True) occurrenceStatus = models.TextField(blank=True, null=True) preparations = models.TextField(blank=True, null=True) disposition = models.TextField(blank=True, null=True) associatedReferences = models.TextField(blank=True, null=True) associatedSequences = models.TextField(blank=True, null=True) associatedTaxa = models.TextField(blank=True, null=True) otherCatalogNumbers = models.TextField(blank=True, null=True) occurrenceRemarks = models.TextField(blank=True, null=True) organismID = models.TextField(blank=True, null=True) organismName = models.TextField(blank=True, null=True) organismScope = models.TextField(blank=True, null=True) associatedOccurrences = models.TextField(blank=True, null=True) associatedOrganisms = models.TextField(blank=True, null=True) previousIdentifications = models.TextField(blank=True, null=True) organismRemarks = models.TextField(blank=True, null=True) materialSampleID = models.TextField(blank=True, null=True) eventID = models.TextField(blank=True, null=True) parentEventID = models.TextField(blank=True, null=True) fieldNumber = models.TextField(blank=True, null=True) eventDate = models.TextField(blank=True, null=True) eventTime = models.TextField(blank=True, null=True) startDayOfYear = models.BigIntegerField(blank=True, null=True) endDayOfYear = models.BigIntegerField(blank=True, null=True) year = models.BigIntegerField(blank=True, null=True) month = models.BigIntegerField(blank=True, null=True) day = models.BigIntegerField(blank=True, null=True) verbatimEventDate = models.TextField(blank=True, null=True) habitat = models.TextField(blank=True, null=True) samplingProtocol = models.TextField(blank=True, null=True) samplingEffort = models.TextField(blank=True, null=True) sampleSizeValue = models.TextField(blank=True, null=True) sampleSizeUnit = models.TextField(blank=True, null=True) fieldNotes = models.TextField(blank=True, null=True) eventRemarks = models.TextField(blank=True, null=True) locationID = models.TextField(blank=True, null=True) higherGeographyID = models.TextField(blank=True, null=True) higherGeography = models.TextField(blank=True, null=True) continent = models.TextField(blank=True, null=True) waterBody = models.TextField(blank=True, null=True) islandGroup = models.TextField(blank=True, null=True) island = models.TextField(blank=True, null=True) countryCode = models.TextField(blank=True, null=True) stateProvince = models.TextField() county = models.TextField() municipality = models.TextField() locality = models.TextField() verbatimLocality = models.TextField(blank=True, null=True) verbatimElevation = models.TextField(blank=True, null=True) verbatimDepth = models.TextField(blank=True, null=True) minimumDistanceAboveSurfaceInMeters = models.TextField(blank=True, null=True) maximumDistanceAboveSurfaceInMeters = models.TextField(blank=True, null=True) locationAccordingTo = models.TextField(blank=True, null=True) locationRemarks = models.TextField(blank=True, null=True) decimalLatitude = models.FloatField("Latitud", blank=True, null=True) decimalLongitude = models.FloatField("Longitud", blank=True, null=True) coordinateUncertaintyInMeters = models.FloatField(blank=True, null=True) coordinatePrecision = models.TextField(blank=True, null=True) pointRadiusSpatialFit = models.TextField(blank=True, null=True) verbatimCoordinateSystem = models.TextField(blank=True, null=True) verbatimSRS = models.TextField(blank=True, null=True) footprintWKT = models.TextField(blank=True, null=True) footprintSRS = models.TextField(blank=True, null=True) footprintSpatialFit = models.TextField(blank=True, null=True) georeferencedBy = models.TextField(blank=True, null=True) georeferencedDate = models.TextField(blank=True, null=True) georeferenceProtocol = models.TextField(blank=True, null=True) georeferenceSources = models.TextField(blank=True, null=True) georeferenceVerificationStatus = models.TextField(blank=True, null=True) georeferenceRemarks = models.TextField(blank=True, null=True) geologicalContextID = models.TextField(blank=True, null=True) earliestEonOrLowestEonothem = models.TextField(blank=True, null=True) latestEonOrHighestEonothem = models.TextField(blank=True, null=True) earliestEraOrLowestErathem = models.TextField(blank=True, null=True) latestEraOrHighestErathem = models.TextField(blank=True, null=True) earliestPeriodOrLowestSystem = models.TextField(blank=True, null=True) latestPeriodOrHighestSystem = models.TextField(blank=True, null=True) earliestEpochOrLowestSeries = models.TextField(blank=True, null=True) latestEpochOrHighestSeries = models.TextField(blank=True, null=True) earliestAgeOrLowestStage = models.TextField(blank=True, null=True) latestAgeOrHighestStage = models.TextField(blank=True, null=True) lowestBiostratigraphicZone = models.TextField(blank=True, null=True) highestBiostratigraphicZone = models.TextField(blank=True, null=True) lithostratigraphicTerms = models.TextField(blank=True, null=True) group = models.TextField(blank=True, null=True) formation = models.TextField(blank=True, null=True) member = models.TextField(blank=True, null=True) bed = models.TextField(blank=True, null=True) identificationID = models.TextField(blank=True, null=True) identificationQualifier = models.TextField(blank=True, null=True) typeStatus = models.TextField(blank=True, null=True) identifiedBy = models.TextField(blank=True, null=True) dateIdentified = models.TextField(blank=True, null=True) identificationReferences = models.TextField(blank=True, null=True) identificationVerificationStatus = models.TextField(blank=True, null=True) identificationRemarks = models.TextField(blank=True, null=True) taxonID = models.TextField(blank=True, null=True) scientificNameID = models.TextField(blank=True, null=True) acceptedNameUsageID = models.TextField(blank=True, null=True) parentNameUsageID = models.TextField(blank=True, null=True) originalNameUsageID = models.TextField(blank=True, null=True) nameAccordingToID = models.TextField(blank=True, null=True) namePublishedInID = models.TextField(blank=True, null=True) taxonConceptID = models.TextField(blank=True, null=True) scientificName = models.TextField() acceptedNameUsage = models.TextField(blank=True, null=True) parentNameUsage = models.TextField(blank=True, null=True) originalNameUsage = models.TextField(blank=True, null=True) nameAccordingTo = models.TextField(blank=True, null=True) namePublishedIn = models.TextField(blank=True, null=True) namePublishedInYear = models.TextField(blank=True, null=True) higherClassification = models.TextField(blank=True, null=True) kingdom = models.TextField() phylum = models.TextField() clase = models.CharField("class", max_length=254) order = models.TextField() family = models.TextField() genus = models.TextField() subgenus = models.TextField(blank=True, null=True) specificEpithet = models.TextField(blank=True, null=True) infraspecificEpithet = models.TextField(blank=True, null=True) taxonRank = models.TextField(blank=True, null=True) verbatimTaxonRank = models.TextField(blank=True, null=True) vernacularName = models.TextField(blank=True, null=True) nomenclaturalCode = models.TextField(blank=True, null=True) taxonomicStatus = models.TextField(blank=True, null=True) nomenclaturalStatus = models.TextField(blank=True, null=True) taxonRemarks = models.TextField(blank=True, null=True) datasetKey = models.TextField(blank=True, null=True) publishingCountry = models.TextField(blank=True, null=True) lastInterpreted = models.TextField(blank=True, null=True) elevation = models.TextField(blank=True, null=True) elevationAccuracy = models.TextField(blank=True, null=True) depth = models.FloatField(blank=True, null=True) depthAccuracy = models.TextField(blank=True, null=True) distanceAboveSurface = models.TextField(blank=True, null=True) distanceAboveSurfaceAccuracy = models.TextField(blank=True, null=True) issue = models.TextField(blank=True, null=True) mediaType = models.TextField(blank=True, null=True) hasCoordinate = models.TextField(blank=True, null=True) hasGeospatialIssues = models.TextField(blank=True, null=True) taxonKey = models.BigIntegerField(blank=True, null=True) acceptedTaxonKey = models.BigIntegerField(blank=True, null=True) kingdomKey = models.BigIntegerField(blank=True, null=True) phylumKey = models.BigIntegerField(blank=True, null=True) classKey = models.BigIntegerField(blank=True, null=True) orderKey = models.BigIntegerField(blank=True, null=True) familyKey = models.BigIntegerField(blank=True, null=True) genusKey = models.BigIntegerField(blank=True, null=True) subgenusKey = models.TextField(blank=True, null=True) speciesKey = models.BigIntegerField(blank=True, null=True) species = models.TextField(blank=True, null=True) genericName = models.TextField(blank=True, null=True) acceptedScientificName = models.TextField(blank=True, null=True) verbatimScientificName = models.TextField(blank=True, null=True) typifiedName = models.TextField(blank=True, null=True) protocol = models.TextField(blank=True, null=True) lastParsed = models.TextField(blank=True, null=True) lastCrawled = models.TextField(blank=True, null=True) repatriated = models.TextField(blank=True, null=True) relativeOrganismQuantity = models.TextField(blank=True, null=True) created_at = models.DateTimeField(auto_now_add=True) geom = PointField() class Meta: verbose_name_plural = 'Ocorrencias' verbose_name = 'Ocurrencia' ordering = ('-created_at', ) def __str__(self): return self.scientificName def save(self, *args, **kwargs): self.geom = { 'type': 'Point', 'coordinates': [self.decimalLongitude, self.decimalLatitude] } super(ImibioOccurrence, self).save(*args, **kwargs)