Google Antigravity: How to use AI to speed up your programming (e.g., Django app)

Video thumbnail

It's time for another practice to expand our capabilities through Artificial Intelligence. This time, we will use Google Antigravity, a modified version of VS Code designed to boost workflow with intelligent agents.

If you want to follow this practice, you can download the tool directly from its official page. The fundamental difference with the traditional editor is that it includes an Agent tab and a Planning tool, which is what we will explore today.

I believe that the current way of programming involves using an AI. If you don't use it, your competition will, and you will lose ground. In this course, we balance traditional teaching with these tools to streamline developments we've already covered previously, such as creating listings and details.

The Project: Blog Module with Django

For this practice, I asked the AI to develop a Blog module that we were missing. The goal was to create:

  1. Post listing: With filters by categories, types, and pagination.
  2. Detail page: Layouted with Bootstrap.
  3. Existing models: Instead of creating a new model from scratch, I instructed it to use our "elementos" model (which simulates posts) and its relations with category and type.

This is the prompt:

Create a module in the elements app to have a Blog with filters by types, category, pagination, and layouted with Bootstrap, containing both the listing and the detail view.

It's a prompt that could be much improved since we did NOT specify aspects like whether we want it to create a model (in our case, we want it to use the Elements relationship):

class Category(models.Model):
    title = models.CharField(max_length=255)
    slug = models.SlugField(max_length=255,blank=True)
    
    def __str__(self):
        return self.title
    
class Type(models.Model):
    title = models.CharField(max_length=255)
    slug = models.SlugField(max_length=255,blank=True)
    
    def __str__(self):
        return self.title
class ElementManager(models.Manager):
    def get_queryset(self):
        # Siempre que usemos Element.objects.all(), incluirá el select_related
        return super().get_queryset().select_related('category', 'type')
    
class Element(models.Model):
    title = models.CharField(max_length=255)
    slug = models.SlugField(max_length=255,blank=True)
    description = models.TextField() # blank=True, null=True
    price = models.DecimalField(max_digits=10,decimal_places=2, default=6.10) # 12345678.10
    category = models.ForeignKey(Category, on_delete=models.CASCADE) #, related_name='elements'
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)
    type = models.ForeignKey(Type, on_delete=models.CASCADE)

We didn't provide screenshots of how we want the development to look, among other aspects you might want to add. However, by indicating which app it needs to inspect (the elements app), we save some tokens and time when Google Antigravity begins to evaluate the project.

Even so, with this, we can interact with the tool and learn how it works.

The Planning Tool

This is the main advantage of Antigravity compared to other tools like Gemini CLI or Agent. Before executing any code, the agent generates a Roadmap.

The AI tells you exactly which files it is going to modify or create:

Add changes to the detail route

Figure 18-4: Roadmap generated by Google Antigravity

As you can see in the Roadmap, the AI wants to generate a new model, which is not what we want (and this is because we gave it a poor prompt), but we have the opportunity to correct it and tell it to "Not create a new model, use the Element one instead."

If the AI tries to create a model named Post and you want it to use Elements, you can add a comment in the planning. It will readjust its plan before touching a single line of code.

As a security recommendation, always sync your project with Git before accepting changes. If the result is not as expected, you can easily go back with a git reset --hard HEAD.

Additionally, the editor once got stuck "Thinking..." indefinitely, because it encountered an error while trying to start the virtual environment and run the command to generate the migrations:

python manage.py makemigrations
zsh: command not found: python

    from django.core.management import execute_from_command_line
ModuleNotFoundError: No module named 'django'

ImportError: Couldn't import Django. Are you sure it's installed and available on your PYTHONPATH environment variable? Did you forget to activate a virtual environment?

I executed the command manually and told the AI ​​Agent to run the command for it, but the Agent still did not respond, so I had to finish its execution and restart it to tell it to continue with the execution of generating the views and templates (which was the next task to perform).

Implementation and Results

After a few iterations in which you must do the same as before, view the Roadmap and if one of the developments suggested by the AI doesn't match what you want to do, add a comment and click the "Proceed" button in the upper right corner until you have a clear Roadmap for your application.

In the end, the AI generated a functional layout based on Bootstrap cards with filters for categories and listings, and a detail page:

Resulting blog

Figure 18-5: Obtained design

Features of the generated development

Dynamic Filters: The view optionally checks if a category or type parameter exists in the URL and adjusts the initial query:

elements\views.py

def blog_list(request):
    elements = Element.objects.select_related('category', 'type').all()
    
    # Filters
    type_slug = request.GET.get('type')
    category_slug = request.GET.get('category')
    if type_slug:
        elements = elements.filter(type__slug=type_slug)
    
    if category_slug:
        elements = elements.filter(category__slug=category_slug)

Query Optimization: It used select_related to fetch category and type relationships, avoiding the N+1 query problem (a common error that slows down applications):

elements = Element.objects.select_related('category', 'type').all()

elements\views.py

Slug Handling: It configured the routes to use the slug field instead of the ID (PK), which is much better for SEO:

elements\urls.py

path('blog/<slug:slug>/', blog_detail, name='blog_detail'),

elements\views.py

def blog_detail(request, slug):
    element = get_object_or_404(Element, slug=slug)
    return render(request, 'elements/blog_detail.html', {'element': element})

Pagination: It implemented the logic to read the page parameter and pass the corresponding objects to the template.

Conclusions

As we can see, these types of tools give us many advantages in modern development, although you might not get the exact same result if you perform a similar interaction. For example, I did this test twice on the same base project and in the first interaction I had to make additional corrections, such as indicating to use the slug instead of the PK table. Additionally, I completed the development by telling it in a second prompt to apply a similar design and use a similar typography based on reference images for the listing and details:

elements\templates\base.html

<!-- Google Fonts -->
    <link
        href="https://fonts.googleapis.com/css2?family=Lora:ital,wght@0,400;0,700;1,400;1,700&family=Open+Sans:ital,wght@0,300;0,400;0,600;0,700;0,800;1,300;1,400;1,600;1,700;1,800&display=swap"
        rel="stylesheet">
    <!-- Font Awesome -->
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
    <link rel="stylesheet" href="{% static 'css/styles.css' %}">
    <style>
        body {
            font-family: 'Lora', 'Times New Roman', serif;
            font-size: 20px;
            color: #212529;
        }
        h1,
        h2,
        h3,
        h4,
        h5,
        h6 {
            font-family: 'Open Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
            font-weight: 800;
        }
    </style> 

In summary, although the AI can infer design from attached screenshots, manual adjustments are always necessary. For instance, in this practice, we had to fix minor syntax errors in the templates (like improperly closed tags). Remember that these are just tools and they do NOT replace a programmer.

Learn how to boost your software development with Google Antigravity. Discover how to use AI and planning tools to efficiently automate the creation of modules, lists, and dynamic filters.

I agree to receive announcements of interest about this Blog.

Andrés Cruz

ES En español