def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) project = self.get_object() user = self.request.user permissions = Authorization.all_permissions(user, project) last_comments = Comment.objects.filter( project=project ).order_by('-created_on')[0:5] serialized_comments = CommentSerializer(last_comments, many=True).data features = Feature.objects.filter( project=project ).order_by('-created_on') serilized_projects = ProjectDetailedSerializer(project).data context['project'] = serilized_projects context['user'] = user context['last_comments'] = serialized_comments context['last_features'] = features[0:5] context['features'] = features context['permissions'] = permissions context['feature_types'] = project.featuretype_set.all() context['is_suscriber'] = Subscription.is_suscriber(user, project) # EDC layers = Layer.objects.filter(project=project) serialized_layers = LayerSerializer(layers, many=True) context['layers'] = serialized_layers.data return context
def get(self, request, slug, feature_type_slug, feature_id): user = request.user feature = self.get_object() project = feature.project layers = Layer.objects.filter(project=project) serialized_layers = LayerSerializer(layers, many=True) linked_features = FeatureLink.objects.filter( feature_from=feature.feature_id ) serialized_link = FeatureLinkSerializer(linked_features, many=True) events = Event.objects.filter(feature_id=feature.feature_id).order_by('created_on') serialized_events = EventSerializer(events, many=True) context = { 'feature': feature, 'feature_data': feature.custom_fields_as_list, 'feature_types': FeatureType.objects.filter(project=project), 'feature_type': feature.feature_type, 'linked_features': serialized_link.data, 'project': project, 'permissions': Authorization.all_permissions(user, project, feature), 'comments': Comment.objects.filter(project=project, feature_id=feature.feature_id), 'attachments': Attachment.objects.filter( project=project, feature_id=feature.feature_id, object_type='feature'), 'events': serialized_events.data, 'comment_form': CommentForm(), 'layers': serialized_layers.data, } return render(request, 'geocontrib/feature/feature_detail.html', context)
def get_context_data(self, **kwargs): user = self.request.user project = self.get_object() permissions = Authorization.all_permissions(user, project) # On filtre les signalements selon leur statut et l'utilisateur courant features = Feature.handy.availables( user=user, project=project).order_by('-created_on') # On filtre les commentaire selon les signalements visibles last_comments = Comment.objects.filter( project=project, feature_id__in=[feat.feature_id for feat in features]).order_by('-created_on')[0:5] serialized_comments = CommentSerializer(last_comments, many=True).data serilized_projects = ProjectDetailedSerializer(project).data context = super().get_context_data(**kwargs) context['project'] = serilized_projects context['title'] = project.title context['user'] = user context['last_comments'] = serialized_comments context['last_features'] = features[0:5] context['features'] = features context['permissions'] = permissions context['feature_types'] = project.featuretype_set.all() context['is_suscriber'] = Subscription.is_suscriber(user, project) return context
def get(self, request, slug, feature_type_slug, feature_id): user = request.user feature = self.get_object() project = feature.project linked_features = FeatureLink.handy.related(feature.feature_id) serialized_link = FeatureLinkSerializer(linked_features, many=True) events = Event.objects.filter( feature_id=feature.feature_id).order_by('created_on') serialized_events = EventSerializer(events, many=True) context = self.get_context_data(feature_id=feature_id) context['feature'] = feature context['feature_data'] = feature.custom_fields_as_list context['linked_features'] = serialized_link.data context['permissions'] = Authorization.all_permissions( user, project, feature) context['events'] = serialized_events.data context['attachments'] = Attachment.objects.filter( project=project, feature_id=feature.feature_id, object_type='feature') context['comment_form'] = CommentForm() context['project'] = project return render(request, 'geocontrib/feature/feature_detail.html', context)
def get(self, request, slug, feature_type_slug): feature_type = self.get_object() form = FeatureTypeModelForm(instance=feature_type) formset = self.CustomFieldsFormSet(queryset=CustomField.objects.filter( feature_type=feature_type)) project = feature_type.project user = request.user features = Feature.handy.availables(user, project).filter( feature_type=feature_type).order_by('-updated_on')[:5] structure = FeatureTypeSerializer(feature_type, context={'request': request}) context = { 'feature_type': feature_type, 'permissions': Authorization.all_permissions(user, project), 'features': features, 'project': project, 'structure': structure.data, 'form': form, 'formset': formset, 'title': feature_type.title, } return render(request, 'geocontrib/feature_type/feature_type_edit.html', context)
def get(self, request, slug): project = self.get_object() user = request.user slug = request.GET.get('create_from') feature_type = FeatureType.objects.filter(slug=slug).first() if feature_type and isinstance(feature_type, FeatureType): initial = model_to_dict(feature_type) if initial.get('title'): initial.update({ 'title': "{} (Copie {})".format( initial['title'], timezone.now().strftime("%d/%m/%Y %H:%M")) }) form = FeatureTypeModelForm(initial=initial) formset = self.CustomFieldsFormSet( queryset=CustomField.objects.filter( feature_type=feature_type), ) else: form = FeatureTypeModelForm() formset = self.CustomFieldsFormSet( queryset=CustomField.objects.none()) context = { 'form': form, 'formset': formset, 'permissions': Authorization.all_permissions(user, project), 'feature_types': project.featuretype_set.all(), 'project': project, 'title': "Création d'un type de signalement", } return render(request, 'geocontrib/feature_type/feature_type_create.html', context)
def post(self, request, slug): user = request.user form = FeatureTypeModelForm(request.POST or None) project = self.get_object() formset = self.CustomFieldsFormSet(request.POST or None) if form.is_valid() and formset.is_valid(): feature_type = form.save(commit=False) feature_type.project = project feature_type.save() for data in formset.cleaned_data: if not data.get("DELETE"): CustomField.objects.create( feature_type=feature_type, position=data.get("position"), label=data.get("label"), name=data.get("name"), field_type=data.get("field_type"), options=data.get("options"), ) return redirect('geocontrib:project', slug=project.slug) else: context = { 'form': form, 'formset': formset, 'permissions': Authorization.all_permissions(user, project), 'feature_types': project.featuretype_set.all(), 'project': project, 'title': "Création d'un type de signalement", } return render(request, 'geocontrib/feature_type/feature_type_create.html', context)
def get(self, request, slug, *args, **kwargs): project = self.get_object() user = request.user layers = Layer.objects.filter(project=project).order_by('order') serialized_layers = LayerSerializer(layers, many=True) permissions = Authorization.all_permissions(user, project) feature_types = FeatureType.objects.filter(project=project) features = Feature.handy.availables(user, project).order_by('-updated_on') filters = {} filters['status'] = request.GET.get('status', None) filters['feature_type__slug'] = request.GET.get('feature_type', None) filters['title__icontains'] = request.GET.get('title', None) if filters: filters = {k: v for k, v in filters.items() if v is not None} features = features.filter(**filters) context = { 'features': features, 'feature_types': feature_types, 'layers': serialized_layers.data, 'project': project, 'permissions': permissions, 'status_choices': Feature.STATUS_CHOICES, } return render(request, 'geocontrib/feature/feature_list.html', context)
def post(self, request, slug): user = self.request.user project = self.get_object() permissions = Authorization.all_permissions(user, project) formset = ProjectBaseMapInlineFormset(data=request.POST or None, instance=project) if formset.is_valid(): formset.save() messages.success(request, 'Enregistrement effectué.') return redirect('geocontrib:project_mapping', slug=project.slug) else: logger.debug(formset.errors) messages.error(request, "L'édition des fonds cartographiques a échoué. ") formset = ProjectBaseMapInlineFormset(data=request.POST or None, instance=project) context = { **self.get_context_data(), **{ 'project': project, 'permissions': permissions, 'formset': formset, 'title': project.title, } } return render(request, 'geocontrib/project/project_mapping.html', context)
def post(self, request, slug, feature_type_slug): user = request.user feature_type = self.get_object() form = FeatureTypeModelForm(request.POST or None, instance=feature_type) formset = self.CustomFieldsFormSet(data=request.POST or None) if form.is_valid() and formset.is_valid(): updated_feature_type = form.save() for data in formset.cleaned_data: custom_field = data.pop('id', None) if custom_field and data.get('DELETE'): custom_field.delete() if custom_field and not data.get('DELETE'): for key in [ 'name', 'field_type', 'position', 'label', 'options' ]: setattr(custom_field, key, data.get(key)) custom_field.save() if not custom_field and not data.get('DELETE'): CustomField.objects.create( name=data.get('name'), field_type=data.get('field_type'), position=data.get('position'), label=data.get('label'), options=data.get('options'), feature_type=updated_feature_type, ) return redirect('geocontrib:project', slug=feature_type.project.slug) else: logger.error(form.errors) logger.error(formset.errors) messages.error( request, "Erreur lors de l'édition du type de signalement. ") context = { 'form': form, 'formset': formset, 'permissions': Authorization.all_permissions(user, feature_type.project), 'project': feature_type.project, 'feature_type': feature_type, 'title': feature_type.title } return render(request, 'geocontrib/feature_type/feature_type_edit.html', context)
def get(self, request, slug, feature_type_slug, feature_id): user = request.user feature = self.get_object() project = feature.project feature_type = feature.feature_type layers = Layer.objects.filter(project=project) serialized_layers = LayerSerializer(layers, many=True) extra = CustomField.objects.filter(feature_type=feature_type) availables_features = Feature.objects.filter( project=project, ).exclude(feature_id=feature.feature_id) feature_form = FeatureBaseForm( instance=feature, feature_type=feature_type, user=user) extra_form = FeatureExtraForm(feature=feature, extra=extra) linked_features = FeatureLink.objects.filter( feature_from=feature.feature_id ).annotate( feature_id=F('feature_to')).values('relation_type', 'feature_id') linked_formset = self.LinkedFormset( form_kwargs={'feature_type': feature_type, 'feature': feature}, prefix='linked', initial=linked_features, queryset=FeatureLink.objects.filter(feature_from=feature.feature_id)) attachments = Attachment.objects.filter( project=project, feature_id=feature.feature_id, object_type='feature' ) attachment_formset = self.AttachmentFormset( prefix='attachment', initial=attachments.values(), queryset=attachments ) context = { 'feature': feature, 'features': Feature.handy.availables(user, project).order_by('updated_on'), 'feature_data': feature.custom_fields_as_list, 'feature_types': FeatureType.objects.filter(project=project), 'feature_type': feature.feature_type, 'project': project, 'permissions': Authorization.all_permissions(user, project, feature), 'feature_form': feature_form, 'extra_form': extra_form, 'availables_features': availables_features, 'linked_formset': linked_formset, 'attachment_formset': attachment_formset, 'attachments': attachments, 'action': 'update', 'layers': serialized_layers.data } return render(request, 'geocontrib/feature/feature_edit.html', context)
def get(self, request, slug): project = get_object_or_404(Project, slug=slug) form = ProjectModelForm(instance=project) context = { 'form': form, 'project': project, 'permissions': Authorization.all_permissions(request.user, project), 'feature_types': project.featuretype_set.all(), 'is_suscriber': Subscription.is_suscriber(request.user, project), 'action': 'update' } return render(request, 'geocontrib/project/project_edit.html', context)
def get(self, request, slug): project = self.get_object() user = request.user form = FeatureTypeModelForm() formset = self.CustomFieldsFormSet(queryset=CustomField.objects.none()) context = { 'form': form, 'formset': formset, 'permissions': Authorization.all_permissions(user, project), 'feature_types': project.featuretype_set.all(), 'project': project, } return render(request, 'geocontrib/feature_type/feature_type_create.html', context)
def get(self, request, slug): user = self.request.user project = self.get_object() permissions = Authorization.all_permissions(user, project) formset = ProjectBaseMapInlineFormset(instance=project) context = {**self.get_context_data(), **{ 'project': project, 'permissions': permissions, 'formset': formset, 'title': project.title, }} return render(request, 'geocontrib/project/project_mapping.html', context)
def post(self, request, slug): project = self.get_object() form = ProjectModelForm(request.POST, request.FILES, instance=project) if form.is_valid() and form.has_changed(): form.save() return redirect('geocontrib:project', slug=project.slug) context = { 'form': form, 'project': project, 'permissions': Authorization.all_permissions(request.user, project), 'feature_types': project.featuretype_set.all(), 'is_suscriber': Subscription.is_suscriber(request.user, project), 'action': 'update' } return render(request, 'geocontrib/project/project_edit.html', context)
def get(self, request, slug): user = self.request.user project = self.get_object() formset = self.AuthorizationFormSet( queryset=Authorization.objects.filter( project=project, user__is_active=True)) authorised = Authorization.objects.filter(project=project) permissions = Authorization.all_permissions(user, project) context = { "title": "Gestion des membres du projet {}".format(project.title), 'authorised': authorised, 'permissions': permissions, 'project': project, 'formset': formset, 'feature_types': FeatureType.objects.filter(project=project) } return render(request, 'geocontrib/project/project_members.html', context)
def get(self, request, slug, feature_type_slug): user = request.user feature_type = self.get_object() project = feature_type.project permissions = Authorization.all_permissions(user, project) extra = CustomField.objects.filter(feature_type=feature_type) feature_form = FeatureBaseForm(feature_type=feature_type, user=user) extra_form = FeatureExtraForm(extra=extra) linked_formset = self.LinkedFormset( form_kwargs={'feature_type': feature_type}, prefix='linked', queryset=FeatureLink.objects.none()) attachment_formset = self.AttachmentFormset( prefix='attachment', queryset=Attachment.objects.none()) context = { **self.get_context_data(), **{ 'features': Feature.handy.availables(user, project).order_by('updated_on'), 'feature_type': feature_type, 'project': project, 'permissions': permissions, 'feature_form': feature_form, 'extra_form': extra_form, 'linked_formset': linked_formset, 'attachment_formset': attachment_formset, 'action': 'create', } } return render(request, 'geocontrib/feature/feature_edit.html', context)
def get(self, request, slug): user = self.request.user project = self.get_object() permissions = Authorization.all_permissions(user, project) # On filtre les signalements selon leur statut et l'utilisateur courant features = Feature.handy.availables( user=user, project=project).order_by('-created_on') # On filtre les commentaire selon les signalements visibles last_comments = Comment.objects.filter( project=project, feature_id__in=[feat.feature_id for feat in features]).order_by('-created_on')[0:5] serialized_comments = CommentSerializer(last_comments, many=True).data data = { 'last_comments': serialized_comments, } return Response(data, status=200)
def post(self, request, slug): user = self.request.user project = self.get_object() formset = self.AuthorizationFormSet(request.POST or None) authorised = Authorization.objects.filter(project=project) permissions = Authorization.all_permissions(user, project) if formset.is_valid(): for data in formset.cleaned_data: # id contient l'instance si existante authorization = data.pop("id", None) if data.get("DELETE"): if authorization: # On ne supprime pas l'utilisateur, mais on cache # ses references dans le signalement if not authorization.user.is_superuser: # hide_feature_user(project, user) pass authorization.delete() else: continue elif authorization: authorization.level = data.get('level') authorization.save() return redirect('geocontrib:project_members', slug=slug) else: logger.error(formset.errors) context = { "title": "Gestion des membres du projet {}".format(project.title), 'authorised': authorised, 'permissions': permissions, 'project': project, 'formset': formset, 'feature_types': FeatureType.objects.filter(project=project) } return render(request, 'geocontrib/project/project_members.html', context)
def get(self, request, slug, feature_type_slug): feature_type = self.get_object() project = feature_type.project user = request.user features = Feature.handy.availables( user, project ).filter( feature_type=feature_type ).order_by('-updated_on')[:5] structure = FeatureTypeSerializer(feature_type, context={'request': request}) context = { 'feature_type': feature_type, 'permissions': Authorization.all_permissions(user, project), 'feature_types': project.featuretype_set.all(), 'features': features, 'project': project, 'structure': structure.data } return render(request, 'geocontrib/feature_type/feature_type_detail.html', context)
def get(self, request, slug, *args, **kwargs): project = self.get_object() user = request.user permissions = Authorization.all_permissions(user, project) feature_types = FeatureType.objects.filter(project=project) features = Feature.handy.availables(user, project).order_by('-updated_on') filters = {} filters['status'] = request.GET.get('status', None) filters['feature_type__slug'] = request.GET.get('feature_type', None) filters['title__icontains'] = request.GET.get('title', None) if filters: filters = {k: v for k, v in filters.items() if v is not None} features = features.filter(**filters) context = self.get_context_data() context['features'] = features context['feature_types'] = feature_types context['project'] = project context['permissions'] = permissions context['status_choices'] = Feature.STATUS_CHOICES return render(request, 'geocontrib/feature/feature_list.html', context)
def get(self, request): data = {} user = request.user for project in Project.objects.all(): data[project.slug] = Authorization.all_permissions(user, project) return Response(data=data, status=200)
def post(self, request, slug, feature_type_slug, feature_id): feature = self.get_object() project = feature.project user = request.user form = CommentForm(request.POST, request.FILES) linked_features = FeatureLink.objects.filter( feature_from=feature.feature_id ) serialized_link = FeatureLinkSerializer(linked_features, many=True) if form.is_valid(): try: comment = Comment.objects.create( feature_id=feature.feature_id, feature_type_slug=feature.feature_type.slug, author=user, project=project, comment=form.cleaned_data.get('comment') ) up_file = form.cleaned_data.get('attachment_file') title = form.cleaned_data.get('title') info = form.cleaned_data.get('info') if comment and up_file and title: Attachment.objects.create( feature_id=feature.feature_id, author=user, project=project, comment=comment, attachment_file=up_file, title=title, info=info, object_type='comment' ) except Exception as err: logger.exception('CommentCreate.post') messages.error( request, "Erreur à l'ajout du commentaire: {err}".format(err=err)) else: # Un evenement est ajouter lors de la creation d'un commentaire # au niveau des trigger. messages.info(request, "Ajout du commentaire confirmé") return redirect( 'geocontrib:feature_detail', slug=slug, feature_type_slug=feature_type_slug, feature_id=feature_id) else: logger.error(form.errors) events = Event.objects.filter(feature_id=feature.feature_id).order_by('created_on') serialized_events = EventSerializer(events, many=True) context = { 'feature': feature, 'feature_data': feature.custom_fields_as_list, 'feature_types': FeatureType.objects.filter(project=project), 'feature_type': feature.feature_type, 'linked_features': serialized_link.data, 'project': project, 'permissions': Authorization.all_permissions(user, project, feature), 'comments': Comment.objects.filter(project=project, feature_id=feature.feature_id), 'attachments': Attachment.objects.filter( project=project, feature_id=feature.feature_id, object_type='feature'), 'events': serialized_events.data, 'comment_form': CommentForm(), } return render(request, 'geocontrib/feature/feature_detail.html', context)
def post(self, request, slug, feature_type_slug, feature_id): user = request.user feature = self.get_object() project = feature.project feature_type = feature.feature_type availables_features = Feature.handy.availables( user=user, project=project, ).exclude(feature_id=feature.feature_id) extra = CustomField.objects.filter(feature_type=feature_type) feature_form = FeatureBaseForm(request.POST, instance=feature, feature_type=feature_type, user=user) extra_form = FeatureExtraForm(request.POST, feature=feature, extra=extra) linked_formset = self.LinkedFormset( request.POST, prefix='linked', form_kwargs={ 'feature_type': feature_type, 'feature': feature }, queryset=FeatureLink.objects.filter( feature_from=feature.feature_id)) attachments = Attachment.objects.filter(project=project, feature_id=feature.feature_id, object_type='feature') attachment_formset = self.AttachmentFormset(request.POST or None, request.FILES, prefix='attachment') old_status = feature.status old_geom = feature.geom.wkt if feature.geom else '' all_forms = [ feature_form, extra_form, attachment_formset, linked_formset, ] forms_are_valid = all([ff.is_valid() for ff in all_forms]) if not forms_are_valid: logger.error([ff.errors for ff in all_forms]) logger.error(request.POST) logger.error(request.FILES) messages.error(request, "Erreur à la mise à jour du signalement. ") context = { **self.get_context_data(), **{ 'feature': feature, 'features': Feature.handy.availables(user, project).order_by('updated_on'), 'feature_types': FeatureType.objects.filter(project=project), 'feature_type': feature.feature_type, 'project': project, 'permissions': Authorization.all_permissions(user, project), 'feature_form': feature_form, 'extra_form': extra_form, 'availables_features': availables_features, 'linked_formset': linked_formset, 'attachment_formset': attachment_formset, 'attachments': attachments, 'action': 'update', } } return render(request, 'geocontrib/feature/feature_edit.html', context) else: updated_feature = feature_form.save(project=project, feature_type=feature_type, extra=extra_form.cleaned_data) # On contextualise l'evenement en fonction des modifications apportés data = {} data['extra'] = updated_feature.feature_data data['feature_title'] = updated_feature.title data['feature_status'] = { 'has_changed': (old_status != updated_feature.status), 'old_status': old_status, 'new_status': updated_feature.status, } data['feature_geom'] = { 'has_changed': (old_geom != updated_feature.geom), 'old_geom': old_geom, 'new_geom': updated_feature.geom.wkt if updated_feature.geom else '', } Event.objects.create( feature_id=updated_feature.feature_id, event_type='update', object_type='feature', user=user, project_slug=updated_feature.project.slug, feature_type_slug=updated_feature.feature_type.slug, data=data) # Traitement des signalements liés for data in linked_formset.cleaned_data: feature_link = data.pop('id', None) if feature_link: if not data.get('DELETE'): feature_link.relation_type = data.get('relation_type') feature_link.feature_to = data.get('feature_to') feature_link.save() if data.get('DELETE'): feature_link.delete() if not feature_link and not data.get('DELETE'): FeatureLink.objects.create( relation_type=data.get('relation_type'), feature_from=updated_feature, feature_to=data.get('feature_to')) # Traitement des piéces jointes for data in attachment_formset.cleaned_data: attachment = data.pop('id', None) if attachment and data.get('DELETE'): attachment.delete() if attachment and not data.get('DELETE'): attachment.attachment_file = data.get('attachment_file') attachment.title = data.get('title') attachment.info = data.get('info') attachment.save() if not attachment and not data.get('DELETE'): Attachment.objects.create( attachment_file=data.get('attachment_file'), title=data.get('title'), info=data.get('info'), object_type='feature', project=project, feature_id=feature_id, author=user, ) return redirect('geocontrib:feature_detail', slug=project.slug, feature_type_slug=feature_type.slug, feature_id=feature.feature_id)
def post(self, request, slug, feature_type_slug): user = request.user feature_type = self.get_object() project = feature_type.project permissions = Authorization.all_permissions(user, project) feature_form = FeatureBaseForm(request.POST, feature_type=feature_type, user=user) extra = CustomField.objects.filter(feature_type=feature_type) extra_form = FeatureExtraForm(request.POST, extra=extra) linked_formset = self.LinkedFormset( request.POST or None, prefix='linked', form_kwargs={'feature_type': feature_type}, ) attachment_formset = self.AttachmentFormset(request.POST or None, request.FILES, prefix='attachment') all_forms = [ feature_form, extra_form, attachment_formset, linked_formset, ] forms_are_valid = all([ff.is_valid() for ff in all_forms]) if forms_are_valid: try: feature = feature_form.save(project=project, feature_type=feature_type, creator=user, extra=extra_form.cleaned_data) except Exception as err: logger.exception('FeatureCreate.post') messages.error( request, "Une erreur s'est produite lors de la création du signalement {title}: {err}" .format(title=feature_form.cleaned_data.get( 'title', 'N/A'), err=str(err))) else: # Traitement des signalements liés for data in linked_formset.cleaned_data: feature_link = data.pop('id', None) if feature_link: if not data.get('DELETE'): feature_link.relation_type = data.get( 'relation_type') feature_link.feature_to = data.get('feature_to') feature_link.save() if data.get('DELETE'): feature_link.delete() if not feature_link and not data.get('DELETE'): FeatureLink.objects.create( relation_type=data.get('relation_type'), feature_from=feature, feature_to=data.get('feature_to')) # Traitement des piéces jointes for data in attachment_formset.cleaned_data: attachment = data.pop('id', None) if attachment and data.get('DELETE'): attachment.delete() if attachment and not data.get('DELETE'): attachment.attachment_file = data.get( 'attachment_file') attachment.title = data.get('title') attachment.info = data.get('info') attachment.save() if not attachment and not data.get('DELETE'): Attachment.objects.create( attachment_file=data.get('attachment_file'), title=data.get('title'), info=data.get('info'), object_type='feature', project=project, feature_id=feature.feature_id, author=user, ) messages.info( request, "Le signalement {title} a bien été créé. ".format( title=feature.title, )) return redirect('geocontrib:feature_detail', slug=project.slug, feature_type_slug=feature_type.slug, feature_id=feature.feature_id) else: logger.error([ff.errors for ff in all_forms]) linked_formset = self.LinkedFormset( request.POST or None, prefix='linked', form_kwargs={'feature_type': feature_type}, ) attachment_formset = self.AttachmentFormset(request.POST or None, request.FILES, prefix='attachment') context = { **self.get_context_data(), **{ 'features': Feature.handy.availables(user, project).order_by('updated_on'), 'feature_type': feature_type, 'project': project, 'permissions': permissions, 'feature_form': feature_form, 'extra_form': extra_form, 'linked_formset': linked_formset, 'attachment_formset': attachment_formset, 'action': 'create', } } return render(request, 'geocontrib/feature/feature_edit.html', context)