0

I get an AttributeError at /accounts/vendor/menuBuilder/category/add/ 'str' object has no attribute 'field' error in my html add form. The edit form works perfectly. And the add form is essentially a direct copy with the exception of the form action.

I've looked through this more than a dozen times and am stumped. Thanks for any help.

Here's the form:

{% extends 'v_base.html' %}
{% load static %}
{% load widget_tweaks %}

{% block content %}

<!-- start page title -->
<div class="row">
    <div class="col-12">
        <div class="page-title-box d-flex align-items-center justify-content-between">
            <h4 class="mb-0 font-size-18">{{vendor.vendor_name}} Profile</h4>
            <button class="btn btn-outline-secondary btn-sm m-1 float-right" onclick="history.back()"><i class="fa fa-angle-left"></i> Back</button>
        </div>
    </div>
</div>
<!-- end page title -->

<div class="row">
    <div class="col-12">
        <!-- Error Messages -->
        <!-- LOAD MESSAGES -->
        {% include 'includes/alerts.html' %}
        <!-- END Error Messages -->

    <div class="card ">
        <div class="card-body">    
            <h3 class="card-title">Add Category</h3>
            <!-- RENDER FORM -->
            <form action="{% url 'addCategory' %}" method="POST">
            {% csrf_token %}

                <div class="row">
                    <div class="col-lg-10">
                        <div class="form-group row">
                            <label for="example-text-input" class="col-sm-2 col-form-label">Category Name</label>
                            <div class="col-sm-6">
                                {% render_field form.category_name type="text" class="form-control" %}
                            </div>
                        </div>
                        <div class="form-group row">
                            <label for="example-text-input" class="col-sm-2 col-form-label">Description</label>
                            <div class="col-sm-6">
                                {% render_field form.description type="textarea" class="form-control" rows="4" %}
                            </div>
                        </div>
                    </div>  
                </div>

                {% for field in form %}
                    {% if field.errors %}
                        {% for error in field.errors %}
                            <li style="color: red;">{{ error }}</li>
                        {% endfor %}
                    {% endif %}
                {% endfor %}
                <button type="submit" class="btn btn-info w-lg"><i class="fa fa-check" aria-hidden="true"></i>Create Category</button>
                </form>
            </div>
        </div>
    </div> <!-- end col -->
</div> <!-- end row --> 
{% endblock %}`

urls.py

from django.urls import path, include
from . import views
from accounts import views as AccountViews

urlpatterns = [
    path('', AccountViews.vendorDashboard, name='vendor'),
    path('vendorProfile/', views.vendorProfile, name='vendorProfile'),
    path('vendorInbox/', views.vendorInbox, name='vendorInbox'),
    path('vendorCalendar/', views.vendorCalendar, name='vendorCalendar'),
    path('vendorListings/', views.vendorListings, name='vendorListings'),
    path('menuBuilder/', views.menuBuilder, name='menuBuilder'),
    path('menuBuilder/category/\<int:pk\>/', views.product_by_category, 
    name='product_by_category'),

    # Category CRUD
    path('menuBuilder/category/add/', views.addCategory, name='addCategory'),
    path('menuBuilder/category/edit/<int:pk>/', views.editCategory, name='editCategory'),
]

view.py

from django.http.response import HttpResponse
from django.shortcuts import render, redirect, get_object_or_404
from django.contrib import messages
from django.contrib.auth.decorators import login_required, user_passes_test
from django.template.defaultfilters import slugify

from .models import Vendor
from .forms import VendorForm
from accounts.forms import UserProfileForm
from accounts.models import UserProfile
from accounts.views import check_role_vendor
from menu.models import Category, Product
from menu.forms import CategoryForm

def get_vendor(request):
    vendor = Vendor.objects.get(user=request.user)
    return vendor

def addCategory(request):
    if request.method == 'POST':
        form = CategoryForm(request.POST)
        if form.is_valid():
            category_name   = form.cleaned_data['category_name']
            category        = form.save(commit=False)
            category.vendor = get_vendor(request)
            category.slug   = slugify(category_name)
            form.save()
            messages.success(request, 'Category added successfully.')
            return redirect('menuBuilder')
        else:
            error_message = form.errors
            messages.error(request, error_message)
    else:
        form = CategoryForm()
    context = {
        'form': form
    }
    return render(request, 'vendor/addCategory.html')

models.py

from django.db import models
from vendor.models import Vendor

class Category(models.Model):
vendor          = models.ForeignKey(Vendor, on_delete=models.CASCADE)
category_name   = models.CharField(max_length=50, unique=True)
slug            = models.SlugField(max_length=100, unique=True)
description     = models.TextField(max_length=250, blank=True)
created_at      = models.DateTimeField(auto_now_add=True)
updated_at      = models.DateTimeField(auto_now=True)

    class Meta():
        verbose_name        = 'category'
        verbose_name_plural = 'categories'
        
        
    def clean(self):
        self.category_name = self.category_name.capitalize()
         
    
    def __str__(self):
        return self.category_name

settings.py

# Application definition

INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'widget_tweaks',

    'accounts',
    'vendor',
    'menu',

]

I'm at my wits end. I have another add form using widget tweaks that's working perfectly.

Help!

Rico
  • 11
  • 4

1 Answers1

0

I found the problem.

In my views file I wasn't passing the context to the form. I found it by trying to display {{form}}. It was blank. That's when it dawned on me.

Here's the solution. I feel a little silly. Oh, well... God bless being a newbie!

def addCategory(request):
    if request.method == 'POST':
        form = CategoryForm(request.POST)
        if form.is_valid():
            category_name   = form.cleaned_data['category_name']
            category        = form.save(commit=False)
            category.vendor = get_vendor(request)
            category.slug   = slugify(category_name)
            form.save()
            messages.success(request, 'Category added successfully.')
            return redirect('menuBuilder')
        else:
            error_message = form.errors
            messages.error(request, error_message)
    else:
        form = CategoryForm()
    context = {
        'form': form
    }
    return render(request, 'vendor/addCategory.html', context)
Rico
  • 11
  • 4