TicketQuery Wiki Macro

The TicketQuery macro lets you display ticket information anywhere that accepts WikiFormatting. The query language used by the [[TicketQuery]] macro is described in the TracQuery page.

Usage

[[TicketQuery]]

Wiki macro listing tickets that match certain criteria.

This macro accepts a comma-separated list of keyed parameters, in the form "key=value".

If the key is the name of a field, the value must use the syntax of a filter specifier as defined in TracQuery#QueryLanguage. Note that this is not the same as the simplified URL syntax used for query: links starting with a ? character. Commas (,) can be included in field values by escaping them with a backslash (\).

Groups of field constraints to be OR-ed together can be separated by a literal or argument.

In addition to filters, several other named parameters can be used to control how the results are presented. All of them are optional.

The format parameter determines how the list of tickets is presented:

  • list -- the default presentation is to list the ticket ID next to the summary, with each ticket on a separate line.
  • compact -- the tickets are presented as a comma-separated list of ticket IDs.
  • count -- only the count of matching tickets is displayed
  • rawcount -- only the count of matching tickets is displayed, not even with a link to the corresponding query (since 1.1.1)
  • table -- a view similar to the custom query view (but without the controls)
  • progress -- a view similar to the milestone progress bars

The max parameter can be used to limit the number of tickets shown (defaults to 0, i.e. no maximum).

The order parameter sets the field used for ordering tickets (defaults to id).

The desc parameter indicates whether the order of the tickets should be reversed (defaults to false).

The group parameter sets the field used for grouping tickets (defaults to not being set).

The groupdesc parameter indicates whether the natural display order of the groups should be reversed (defaults to false).

The verbose parameter can be set to a true value in order to get the description for the listed tickets. For table format only. deprecated in favor of the rows parameter

The rows parameter can be used to specify which field(s) should be viewed as a row, e.g. rows=description|summary

The col parameter can be used to specify which fields should be viewed as columns. For table format only.

For compatibility with Trac 0.10, if there's a last positional parameter given to the macro, it will be used to specify the format. Also, using "&" as a field separator still works (except for order) but is deprecated.

Examples

Example Result Macro
Number of Triage tickets: 662 [[TicketQuery(status=new&milestone=,count)]]
Number of new tickets: 662 [[TicketQuery(status=new,count)]]
Number of reopened tickets: 0 [[TicketQuery(status=reopened,count)]]
Number of assigned tickets: 393 [[TicketQuery(status=assigned,count)]]
Number of invalid tickets: 5186 [[TicketQuery(status=closed,resolution=invalid,count)]]
Number of worksforme tickets: 1071 [[TicketQuery(status=closed,resolution=worksforme,count)]]
Number of duplicate tickets: 4331 [[TicketQuery(status=closed,resolution=duplicate,count)]]
Number of wontfix tickets: 4129 [[TicketQuery(status=closed,resolution=wontfix,count)]]
Number of fixed tickets: 18582 [[TicketQuery(status=closed,resolution=fixed,count)]]
Number of untriaged tickets (milestone unset): 1055 [[TicketQuery(status!=closed,milestone=,count)]]
Total number of tickets: 35329 [[TicketQuery(count)]]
Number of tickets reported or owned by current user: 1489 [[TicketQuery(reporter=$USER,or,owner=$USER,count)]]
Number of tickets created this month: 61 [[TicketQuery(created=thismonth..,count)]]
Number of closed Firefox tickets: 8 [[TicketQuery(status=closed,keywords~=firefox,count)]]
Number of closed Opera tickets: 24 [[TicketQuery(status=closed,keywords~=opera,count)]]
Number of closed tickets affecting Firefox and Opera: 0 [[TicketQuery(status=closed,keywords~=firefox opera,count)]]
Number of closed tickets affecting Firefox or Opera: 32 [[TicketQuery(status=closed,keywords~=firefox|opera,count)]]
Number of tickets that affect Firefox or are closed and affect Opera: 32 [[TicketQuery(status=closed,keywords~=opera,or,keywords~=firefox,count)]]
Number of closed Firefox tickets that don't affect Opera: 0 [[TicketQuery(status=closed,keywords~=firefox -opera,count)]]
Last 3 modified tickets: #35801, #36109, #25230 [[TicketQuery(max=3,order=modified,desc=1,compact)]]

Details of ticket #1:

[[TicketQuery(id=1,col=id|owner|reporter,rows=summary,table)]]

Ticket Owner Reporter
#1 Jacob Adrian Holovaty
Summary Create architecture for anonymous sessions

Format: list

[[TicketQuery(version=0.6|0.7&resolution=duplicate)]]

This is displayed as:

No results

[[TicketQuery(id=123)]]

This is displayed as:

#123
Typo in the model_api/#field-types

Format: compact

[[TicketQuery(version=0.6|0.7&resolution=duplicate, compact)]]

This is displayed as:

No results

Format: count

[[TicketQuery(version=0.6|0.7&resolution=duplicate, count)]]

This is displayed as:

0

Format: progress

[[TicketQuery(milestone=0.12.8&group=type,format=progress)]]

This is displayed as:

Uncategorized

1997 / 1997

Bug

10122 / 10484

New feature

3699 / 4091

Cleanup/optimization

5240 / 5540

Format: table

You can choose the columns displayed in the table format (format=table) using col=<field>. You can specify multiple fields and the order they are displayed in by placing pipes (|) between the columns:

[[TicketQuery(max=3,status=closed,order=id,desc=1,format=table,col=resolution|summary|owner|reporter)]]

This is displayed as:

Full rows

In table format you can specify full rows using rows=<field>:

[[TicketQuery(max=3,status=closed,order=id,desc=1,format=table,col=resolution|summary|owner|reporter,rows=description)]]

This is displayed as:

Results (1 - 3 of 34274)

1 2 3 4 5 6 7 8 9 10 11
Ticket Resolution Summary Owner Reporter
#36108 invalid The `update_field` when using `django.db.models.signals` does not work with a custom Model Manager NicoJJohnson
Description

I have a Model that has some sensitive objects labeled with is_private=True. Furthermore, all private objects should be filtered out by default, unless there is a User, in which we can check if they own the object.

class SensitiveObjectManager(models.Manager):
    def __init__(self):
        super().__init__()
        self.user = None

    def for_user(self, user):
        """Create a new manager instance with the user context"""
        manager = SensitiveObjectManager()
        manager.model = self.model
        manager.user = user
        if hasattr(self, "core_filters"):
            manager.core_filters = self.core_filters
        return manager

    def get_queryset(self):
        qs = super().get_queryset()

        if hasattr(self, "core_filters"):
            qs = qs.filter(**self.core_filters)

        if self.user is None:
            return qs.filter(is_private=False)
        return qs.filter(Q(is_private=False) | Q(owner=self.user.id))


class SensitiveObject(models.Model):
  objects = SensitiveObjectManager()
  all_objects = models.Manager()

  id = models.UUIDField(primary_key=True, default=uuid.uuid4)
  is_private = models.BooleanField(default=True)
  owner = models.ForeignKey(User)
  is_leaked = models.BooleanField(default=False)

This is designed because SensitiveObject.objects.all() is commonly used throughout our code, but with this Manager, we can always filter out the private objects. To include objects that the user owns, we can use SensitiveObject.objects.for_user(User).all().

Everything works fine with it so far except for a very odd bug using django.db.models.signals.post_save. We want to catch when is_leaked is updated so that we can update a few other Models. So we have

#apps.py
def sensitive_object_updated(sender, instance, created, update_fields, **kwargs):
  # ( Would perform additional ORM logic, but for testing, the print statements are all that's needed)
  print("Instance:")
  print(instance)
  print("Instance.is_private:")
  print(instance.is_private)
  print("Instance.is_leaked:")
  print(instance.is_leaked)
  print("update_fields:")
  print(update_fields)

from django.apps import AppConfig

class SensitiveObjectConfig(AppConfig):
    default_auto_field = "django.db.models.BigAutoField"
    name = "sensitive_object"

    def ready(self):
        from django.db.models.signals import post_save
        from sensitive_object.models import SensitiveObject
        post_save.connect(sensitive_object_updated, sender=SensitiveObject)

If the SensitiveObject.is_private=True, then the update_fields will NOT be included in sensitive_object_updated which is very annoying (update_fields will equal None). But when SensitiveObject.is_private=False, the update_fields work fine. I tested this, and I know it is because of the SensitiveObjectManager. Furthermore, if you test it, you will see the instance and instance.is_leaked have the correct values inside sensitive_object_updated always, (whether if is_private is True or False). I’m pretty confident that this is a bug with Django.

For more information about trying to find a patch, this is also posted on the django forum under the name "Signal does not pick up update_field if the model’s Manager filters objects"

Example Test Case:

# tests.py
from django.test import TestCase
def SensitiveObjectTest(TestCase):
   def example_test(self):
      private_object = SensitiveObject.objects.create(
         owner=self.user,
         is_private=True,
         is_leaked=False
      )
      self.assertTrue(SensitiveObject.all_objects.filter(id=private_dataset.id).exists())
      # Thanks to the SensitiveObjectManager, private datasets are filtered out of objects by default.
      self.assertFalse(SensitiveObject.objects.filter(id=private_dataset.id).exists())
      self.assertTrue(SensitiveObject.objects.for_user(self.user).filter(id=private_dataset.id).exists())

      print("Observe print logs from sensitive_object_updated for private object")
      private_object.is_leaked=True
      private_object.save()
      # Should see the print statements from `senstive_object_updated`.
      # update_fields will be None 

      public_object = SensitiveObject.objects.create(
         owner=self.user,
         is_private=False,
         is_leaked=False
      )
      self.assertTrue(SensitiveObject.all_objects.filter(id=public_dataset.id).exists())
      self.assertTrue(SensitiveObject.objects.filter(id=public_dataset.id).exists())

      print("Observe print logs from sensitive_object_updated for public object")
      public_object.is_leaked=True
      public_object.save()
      # Should see the print statements from `senstive_object_updated`.
      # update_fields will be correct 
#36106 wontfix Exclude option for the "flush" django-admin command Dimitar Zlatanovski
Description

An exclude option for the "flush" django-admin command could be useful in certain cases where we have tables that have been filled with data migrations. Since flush just deletes the data but leaves the migrations untouched, having an exclude option where a user could provide a list of table names to be excluded can come in handy. Example: Country table that has been filled with data using a data migration. Every time we run flush we might want to exclude this table from flushing.

#36101 wontfix Support BIT data type model field for MySQL and PostgreSQL Jordan Bae
Description

Support BIT data type model field for MySQL and PostgreSQL

Currently, Django's model fields do not support the BIT data type which is available in both MySQL and PostgreSQL databases.

Key reasons for adding BIT data type support:

  1. Improved Database Inspection
    • When using inspectdb on tables containing BIT columns, Django currently falls back to TextField with a "This field type is a guess" comment
    • Native BitField support would provide accurate model generation for existing databases
  1. Database-specific Features
    • MySQL: Support for BIT(M) where M can specify the number of bits
    • PostgreSQL: Support for both BIT(n) and BIT VARYING(n) types

  1. Use Cases
    • Efficient storage of boolean flags and bit flags
    • Direct mapping to database-native bit operations
    • Better integration with legacy databases using BIT columns

This enhancement would improve Django's database type coverage and provide more efficient handling of bit-based data.

1 2 3 4 5 6 7 8 9 10 11


See also: TracQuery, TracTickets, TracReports

Last modified 12 months ago Last modified on Jan 24, 2024, 9:58:09 AM
Note: See TracWiki for help on using the wiki.
Back to Top