Closed Joris-Pieters closed 4 years ago
Can you please post some code so it’s easier to understand.
In my case I have a model "project" that contains a CharField "title", and a ForeignKey "company". For "company" I want to use the AddAnotherWidget so the user can add companies (there's more to a "project" of course, but I try to limit the code to only what is relevant):
models:
from django.db import models
class Project(models.Model):
title = models.CharField(max_length = 255)
company = models.ForeignKey(Company, on_delete = models.DO_NOTHING, blank = True, null = True)
def __str__(self):
if self.start_date is None:
return f"{self.company.__str__()}: {self.title.__str__()} "
else:
return f"{self.company.__str__()}: {self.title.__str__()} ({str(self.start_date.year)})"
class Meta:
ordering = [Lower('company'), Lower('title')]
class Company(models.Model):
name = models.CharField(max_length = 255, unique = True, blank = False)
def __str__(self):
return self.name
class Meta:
verbose_name_plural = "Companies"
ordering = [Lower('name')]
views (project_view is function based as this is what I knew when I started while view for company is class based as this is a requirement for AddAnother if I understood well):
from django.shortcuts import render
from django.http import HttpResponse
from django.contrib import messages
from django_addanother.views import CreatePopupMixin
from ..forms import *
from ..models import *
def project_view(request, pk):
if request.user.is_authenticated:
project = Project.objects.get(pk = pk)
request.user.last_watched_project = pk
request.user.save()
if request.method == 'GET':
form = ProjectForm(initial = project.__dict__)
context = {
'form': form,
'jquery': 'admin/js/vendor/jquery/jquery.js',
}
return render(request, "main/project.html", context)
if request.method == 'POST':
form = ProjectForm(request.POST)
context = {
'form': form,
'jquery': 'admin/js/vendor/jquery/jquery.js',
}
if not request.user.is_superuser:
messages.error(request, "You do not have the proper rights to change this.")
return render(request, "main/project.html", context)
if form.is_valid():
project = form.save()
messages.success(request, "Project saved.")
return render(request, "main/projects.html")
else:
messages.error(request, "One or more required fields are empty.")
return render(request, "main/project.html", context)
class CreateCompany(CreatePopupMixin, generic.CreateView):
model = Company
fields = ['name']
forms:
from django import forms
from django_addanother.widgets import AddAnotherWidgetWrapper
from main.models import *
class ProjectForm(forms.ModelForm):
class Meta:
model = Project
fields = ('title', 'company')
widgets = {
'company': AddAnotherWidgetWrapper(
forms.Select(),
'/company',
),
}
class CompanyForm(forms.ModelForm):
class Meta:
model = Project
fields = '__all__'
urls:
from django.conf.urls.static import static
from django.urls import path
from references import settings
from . import views
app_name = 'main'
urlpatterns = [
path("", views.home, name = "home"),
path("project/<int:pk>/", views.project_view, name = "project_view"),
path("company", views.company_view.CreateCompany.as_view(), name = "company_view"),
] + static(settings.MEDIA_URL, document_root = settings.MEDIA_ROOT)
Problem: Let's say I made a project with name = "first project" and company = "EvilCorp". If I check in admin this is saved properly, even if I created "EvilCorp" on the spot using the AddAnotherWidget (so that is working great!). When I load this project back to a form for editing however the field name correctly contains "first project", while company gives the default value of "------". Same goes for other "classic" widgets versus AddAnotherWidgets.
Thanks for your support!
My bad, this wasn't an issue with AddAnotherWidgets, but my very own mistake.
in the views
form = ProjectForm(initial = project.__dict__)
should be
form = ProjectForm(instance = project)
Thanks for your great work.
I'm not sure if this is a bug or a mistake on my side (more likely), but when I load an existing instance in a form the AddAnotherWidgets are not filled with the current value. The "normal" fields are filled however.
I based my code on the example app, but that only has a submit option and does not let you load an existing instance.
Any idea what could be going wrong?