I'm trying to create a detail view for the model PROJECT. In the detail view, I want to also include a model TASK and all the related objects in ATTACHMENTS to each task.
Models.py - Task
Models.py - Attachment
Views.py - Project Detail
Template -
-- I'd like to do something like this -
{for task in task list}
{task}
{for attachments in task}
{attachment}
{end for}
{end for}
Here are snippets of the working files. Thanks in advance for any help!!
Models.py - Project
class Project(NamedModel): """An Asana project in a workspace having a collection of tasks.""" layout_choices = ( ('board', _('board')), ('list', _('list')), )
archived = models.BooleanField(default=False) color = models.CharField(choices=COLOR_CHOICES, max_length=16, null=True, blank=True) created_at = models.DateTimeField(auto_now_add=True) current_status = models.ForeignKey( 'ProjectStatus', null=True, on_delete=models.SET_NULL, related_name='current_status') custom_field_settings = models.ManyToManyField( 'CustomField', through='CustomFieldSetting', related_name='custom_field_settings') due_date = models.DateField(null=True, blank=True) due_on = models.DateField(null=True, blank=True) followers = models.ManyToManyField('User', related_name='projects_following', blank=True) html_notes = models.TextField(null=True, blank=True) layout = models.CharField(choices=layout_choices, max_length=16) members = models.ManyToManyField('User', blank=True) modified_at = models.DateTimeField(auto_now=True) notes = models.TextField(null=True, blank=True) owner = models.ForeignKey( 'User', to_field='remote_id', related_name='projects_owned', null=True, on_delete=models.SET_NULL) public = models.BooleanField(default=False) resource_type = models.CharField(max_length=24, null=True, blank=True, default='project') start_on = models.DateField(null=True, blank=True) team = models.ForeignKey('Team', to_field='remote_id', null=True, on_delete=models.SET_NULL) workspace = models.ForeignKey('Workspace', to_field='remote_id', on_delete=models.CASCADE)
def asana_url(self, **kwargs): """Returns the absolute url for this project at Asana.""" return '{}{}/list'.format(ASANA_BASE_URL, self.remote_id)
class Task(Hearted, NamedModel): """An Asana task; something that needs doing.""" status_choices = ( ('inbox', _('inbox')), ('upcoming', _('upcoming')), ('later', _('later')), ) subtype_choices = ( ('default_task', _('default task')), ('section', _('section')), )
assignee = models.ForeignKey( 'User', to_field='remote_id', related_name='assigned_tasks', null=True, blank=True, on_delete=models.SET_NULL) assignee_status = models.CharField(choices=status_choices, max_length=16) completed = models.BooleanField(default=False) completed_at = models.DateTimeField(null=True, blank=True) custom_fields = models.TextField(null=True, blank=True) created_at = models.DateTimeField(auto_now_add=True) dependencies = models.ManyToManyField('self', symmetrical=False, related_name='dependents') due_at = models.DateTimeField(null=True, blank=True) due_on = models.DateField(null=True, blank=True) followers = models.ManyToManyField('User', related_name='tasks_following') html_notes = models.TextField(null=True, blank=True) modified_at = models.DateTimeField(auto_now=True) notes = models.TextField(null=True, blank=True) parent = models.ForeignKey( 'self', to_field='remote_id', null=True, blank=True, on_delete=models.SET_NULL) projects = models.ManyToManyField('Project') resource_subtype = models.CharField( choices=subtype_choices, max_length=24, default='default_task') resource_type = models.CharField(max_length=24, null=True, blank=True, default='task') start_on = models.DateField(null=True, blank=True) tags = models.ManyToManyField('Tag')
def _asana_project_url(self, project): return '{}{}/{}/list'.format(ASANA_BASE_URL, project.workspace.remote_id, self.remote_id)
def asana_url(self, **kwargs): """Returns the absolute url for this task at Asana.""" if 'project' in kwargs: return self._asana_project_url(kwargs['project']) projects = self.projects.all() if len(projects) == 1: project = projects[0] return self._asana_project_url(project) return super(Task, self).asana_url()
def delete_from_asana(self, *args, **kwargs): """Deletes this task from Asana and then deletes this model instance.""" client = client_connect() client.tasks.delete(self.remote_id) logger.debug('Deleted asana task %s', self.name) return self.delete(*args, **kwargs)
def due(self): return self.due_at or self.due_on due.admin_order_field = 'due_on'
def refresh_from_asana(self): """Updates this task from Asana.""" client = client_connect() task_dict = client.tasks.find_by_id(self.remote_id) if task_dict['assignee']: user = User.objects.get_or_create( remote_id=task_dict['assignee']['id'], defaults={'name': task_dict['assignee']['name']})[0] task_dict['assignee'] = user task_dict.pop('id') task_dict.pop('dependents', None) dependencies = task_dict.pop('dependencies', None) task_dict.pop('hearts', None) task_dict.pop('memberships') task_dict.pop('num_hearts', None) task_dict.pop('projects') task_dict.pop('workspace') followers_dict = task_dict.pop('followers') tags_dict = task_dict.pop('tags') for field, value in task_dict.items(): setattr(self, field, value) self.save() follower_ids = [follower['id'] for follower in followers_dict] followers = User.objects.filter(id__in=follower_ids) self.followers.set(followers) for tag_ in tags_dict: tag = Tag.objects.get_or_create( remote_id=tag_['id'], defaults={'name': tag_['name']})[0] self.tags.add(tag) if dependencies: self.dependencies.set([dep['id'] for dep in dependencies])
def sync_to_asana(self, fields=None): """Updates Asana to match values from this task.""" fields = fields or ['completed'] data = {} for field in fields: data[field] = getattr(self, field) client = client_connect() client.tasks.update(self.remote_id, data) logger.debug('Updated asana for task %s', self.name)
def add_comment(self, text): """Adds a comment in Asana for this task.""" client = client_connect() response = client.tasks.add_comment(self.remote_id, {'text': text}) logger.debug('Added comment for task %s: %s', self.name, text) return response
def get_custom_fields(self): """Returns custom_fields as a dict""" response = json.loads(self.custom_fields) custom_field_values = {} for custom_field in response: if custom_field['resource_subtype'] == 'enum': custom_field_values[custom_field['name']] = custom_field['enum_value']['name'] elif custom_field['resource_subtype'] == 'number': if custom_field.get('precision', 0): custom_field_values[custom_field['name']] = float(custom_field['number_value']) else: custom_field_values[custom_field['name']] = int(custom_field['number_value']) else: custom_field_values[custom_field['name']] = custom_field['text_value'] return custom_field_values
Models.py - Attachment
class Attachment(NamedModel): """A remote file.""" host_choices = ( ('asana', 'asana'), ) type_choices = ( ('image', 'image'), ('other', 'other'), ) created_at = models.DateTimeField(auto_now_add=True) download_url = models.URLField(max_length=1024) host = models.CharField(choices=host_choices, max_length=24) parent = models.ForeignKey('Task', to_field='remote_id', on_delete=models.CASCADE) permanent_url = models.URLField(max_length=1024) resource_type = models.CharField(max_length=24, null=True, blank=True, default='attachment') type = models.CharField(choices=type_choices, max_length=24, null=True, blank=True) view_url = models.URLField(max_length=1024)
def asana_url(self, **kwargs): return self.permanent_url
Views.py - Project Detail
class ProjectDetail(SingleObjectMixin, ListView): queryset = Project.objects.all() template_name = 'dash1/project_detail.html'
def get(self, request, *args, **kwargs): self.object = self.get_object(queryset=Project.objects.all()) return super().get(request, *args, **kwargs)
def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context['Project'] = self.object context['task_list'] = Task.objects.filter(projects=8).order_by('-completed_at', 'name')[:5] context['attachment_list'] = Attachment.objects.all()[:5] return context
Template -
{% block main %}<h1>{{ object }}</h1>{% for object in task_list.all %}<div class="row"> <div class="col-xl-4"> <div class="card-box project-box"> <div class="dropdown float-right"> <a href="#" class="dropdown-toggle card-drop arrow-none" data-toggle="dropdown" aria-expanded="false"> <h3 class="m-0 text-muted"><i class="mdi mdi-dots-horizontal"></i></h3> </a> <div class="dropdown-menu dropdown-menu-right" aria-labelledby="btnGroupDrop1"> <a class="dropdown-item" href="#">Edit</a> <a class="dropdown-item" href="#">Delete</a> <a class="dropdown-item" href="#">Add Members</a> <a class="dropdown-item" href="#">Add Due Date</a> </div> </div> <p class="text-muted text-uppercase mb-0 font-13">DUE: {{ object.due_on }}</p> <h4 class="mt-0 mb-3"><a href="" class="text-dark">{{ object.name }}</a></h4> <p class="text-muted font-13">{{ object.notes }}<a href="#" class="font-600 text-muted">view more</a> </p>
<ul class="list-inline"> {% for object in attachment_list.all %} <li class="list-inline-item"> <img src="{{ object.permanent_url }}" height="30px"> </li> {% endfor %} </ul>
<label class="">Task completed: <span class="text-custom">{{ object.completed_at }}</span></label> </div><!-- /.progress .no-rounded --> </div> </div></div> {% empty %} <p class="lead"> No Tasks Loaded </p> {% endfor %}
{% endblock %}
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/9f7d091c-a40e-4c8a-b290-ef77fe6b9482%40googlegroups.com.
No comments:
Post a Comment