Inline form similar to the admin TabularInLine

I’m trying to make a sales app with what I thought was going to be simple features, but I’m having a lot of struggles with some of those features:

  1. I want to make a form like the ones in the admin panel, with an inline and the possibility to create a new item for a model. I already made one that works exactly as I want it to do so (in the admin panel) for the “Order” model, so I’ll show you the code.
    I also found a way to do it using JS, but I want to know if there’s an easier way.
  2. Auto-populate fields based on other models.

This is the important part of the code that I have so far (without the JS solution):

Models

class Product(models.Model):
    category = models.ForeignKey(
        Category, related_name="products", on_delete=models.CASCADE
    )
    name = models.CharField(max_length=200, db_index=True)
    slug = models.SlugField(max_length=200, db_index=True)
    image = models.ImageField(upload_to="products/%Y/%m/%d", blank=True)
    description = models.TextField(blank=True)
    price = models.DecimalField(max_digits=10, decimal_places=2)
    available = models.BooleanField(default=True)
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)

    class Meta:
        ordering = ("name",)
        index_together = (("id", "slug"),)

    def __str__(self):
        return self.name

    def get_absolute_url(self):
        return reverse("sales:product_detail", args=[self.id, self.slug])

class Order(models.Model):
    customer = models.ForeignKey("Customer", on_delete=models.CASCADE)
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)
    paid = models.BooleanField(default=False)

    class Meta:
        ordering = ("-created",)

    def __str__(self):
        return "Order {}".format(self.id)

    def get_total_cost(self):
        return sum(item.get_cost() for item in self.items.all())


class OrderItem(models.Model):
    order = models.ForeignKey(Order, related_name="items", on_delete=models.CASCADE)
    product = models.ForeignKey(
        Product, related_name="order_items", on_delete=models.CASCADE
    )
    quantity = models.PositiveIntegerField(default=1)

    def __str__(self):
        return "{}".format(self.id)

    def get_cost(self):
        return self.price * self.quantity


class Customer(models.Model):
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)
    phone = models.CharField(max_length=15, null=True)
    email = models.EmailField()
    address_line_1 = models.CharField(max_length=250)
    address_line_2 = models.CharField(max_length=60, null=True)
    postal_code = models.CharField(max_length=20)
    city = models.CharField(max_length=100)
    state = models.CharField(max_length=100, null=True)
    country = models.CharField(max_length=100, default="Mexico")

    def __str__(self):
        return f"{self.first_name} {self.last_name}"

Forms.

I only have the customer form, which works pretty well. I made it that way so I can show the fields with the same format as in a template that I’m using (I know almost nothing about the front end). What I want is a form for the Order model, similar to the one in the admin panel.

class CustomerForm(ModelForm):
    first_name = forms.CharField(
        widget=forms.TextInput(
            attrs={
                "placeholder": "First Name",
                "class": "form-control",
                "type": "text",
            }
        )
    )
    last_name = forms.CharField(
        widget=forms.TextInput(
            attrs={
                "placeholder": "Last Name",
                "class": "form-control",
                "type": "text",
            }
        )
    )
    phone = forms.CharField(
        widget=forms.TextInput(
            attrs={
                "placeholder": "Phone Number",
                "class": "form-control",
                "type": "text",
            }
        )
    )

    email = forms.CharField(
        widget=forms.TextInput(
            attrs={"placeholder": "Email", "class": "form-control", "type": "email"}
        )
    )

    address_line_1 = forms.CharField(
        widget=forms.TextInput(
            attrs={
                "placeholder": "Address Line 1",
                "class": "form-control",
                "type": "text",
            }
        )
    )
    address_line_2 = forms.CharField(
        widget=forms.TextInput(
            attrs={
                "placeholder": "Address Line 2",
                "class": "form-control",
                "type": "text",
            }
        )
    )
    postal_code = forms.CharField(
        widget=forms.TextInput(
            attrs={
                "placeholder": "Postal Code",
                "class": "form-control",
                "type": "number",
            }
        )
    )
    city = forms.CharField(
        widget=forms.TextInput(
            attrs={
                "placeholder": "City",
                "class": "form-control",
                "type": "text",
            }
        )
    )
    state = forms.CharField(
        widget=forms.TextInput(
            attrs={
                "placeholder": "State",
                "class": "form-control",
                "type": "text",
            }
        )
    )
    country = forms.CharField(
        widget=forms.TextInput(
            attrs={
                "placeholder": "Country",
                "class": "form-control",
                "type": "text",
            }
        )
    )

    class Meta:
        model = Customer
        fields = "__all__"

Admin

(it works as I want it to work in a template).

from django.contrib import admin
from .models import Order, OrderItem, Category, Product, Customer


class OrderItemInline(admin.TabularInline):
    model = OrderItem
    raw_id_fields = ["product"]


@admin.register(Order)
class OrderAdmin(admin.ModelAdmin):
    list_display = [
        "id",
        "paid",
        "created",
        "updated",
    ]
    list_filter = ["paid", "created", "updated"]
    inlines = [OrderItemInline]


# register
@admin.register(Category)
class CategoryAdmin(admin.ModelAdmin):
    list_display = ["name", "slug"]
    prepopulated_fields = {"slug": ("name",)}


@admin.register(Product)
class ProductAdmin(admin.ModelAdmin):
    list_display = ["name", "slug", "price", "available", "created"]
    list_filter = ["available", "created", "updated"]
    list_editable = ["price", "available"]
    prepopulated_fields = {"slug": ("name",)}


@admin.register(Customer)
class CustomerAdmin(admin.ModelAdmin):
    list_display = [
        "first_name",
        "last_name",
        "email",
        "address_line_1",
        "address_line_2",
        "postal_code",
        "city",
    ]

I still have neither views nor URLs related to the Order.