I'm getting a "'Document' object is not iterable" error when this form is submitted. It works if 'document' is just taken from the model rather than written with the select2 package. It's extremely similar to the example code from the django_select2 package. I've tried making it Document.objects.all() instead, and that didn't work either.
models.py
class Individual(models.Model):
id = models.CharField(max_length=8, unique=True, verbose_name='ID')
first_name = models.CharField(max_length=50, null=True)
middle_name = models.CharField(max_length=50, blank=True, null=True)
last_name = models.CharField(max_length=100, null=True)
dob = models.CharField(max_length=15, blank=True)
suffix = models.CharField(max_length=25, blank=True, null=True)
time_stamp = models.DateTimeField(auto_now=True)
entered_by = models.CharField(max_length=50)
def _name(self):
return self.first_name + ' ' + self.last_name
class Meta:
db_tablespace = 'name_of_database'
def __unicode__(self):
return self.id
class Document(models.Model):
document_name = models.CharField(max_length=100)
class Meta:
db_tablespace = 'name_of_database'
def __unicode__(self):
return self.document_name
class DocLog(models.Model):
individual = models.ForeignKey('Individual', to_field='id', null=True)
fiscal = models.PositiveIntegerField(db_index=True)
document = models.ManyToManyField(Document, max_length=50,
verbose_name='Document Title')
date_received = models.DateField(editable=True, verbose_name='Date Received')
doc_notes = models.TextField(max_length=500, verbose_name='Document Notes')
time_stamp = models.DateTimeField(auto_now=True)
entered_by = models.CharField(max_length=50)
class Meta:
db_tablespace = 'name_of_database'
verbose_name = 'Document Log'
def __unicode__(self):
return self.individual.id
forms.py
from django import forms
from django_select2 import *
from .models import DocLog, Document
#Document Select2 class
class DocumentChoices(AutoModelSelect2Field):
queryset = Document.objects
search_fields = ['document_name__icontains',]
#New document form
class NewDocument(forms.ModelForm):
document = DocumentChoices()
class Meta:
model = DocLog
fields = ('individual', 'fiscal', 'document', 'date_received', 'doc_notes')
widgets = {
'individual': forms.HiddenInput(),
}
You defined ManyToManyField in your Model, in Modelform ManyToManyField is represented by django.forms.ModelMultipleChoiceField, which is a MultipleChoiceField whose choices are a model QuerySet.
So instead of using AutoModelSelect2Field you use AutoModelSelect2MultipleField
for your case
#Document Select2 class
class DocumentChoices(AutoModelSelect2MultipleField):
queryset = Document.objects
search_fields = ['document_name__icontains',]
Related
I'm working on a form that takes value from another model, and everything is loaded correctly, but when I submit the data the form is showing the following error:
django.db.utils.IntegrityError: NOT NULL constraint failed: account_deal.company_id
The consensus is that you have to add blank=True,null=True but that only prevents the error if the user doesn't type any data, in this case, I'm using an auto-generated date, so not sure why am I getting this error.
views.py
def close_lead(request):
if request.method == 'POST':
deal_form = DealForm(request.POST)
if deal_form.is_valid():
deal_form.save()
messages.success(request, 'You have successfully updated the status from open to Close')
id = request.GET.get('project_id', '')
obj = Leads.objects.get(project_id=id)
obj.status = "Closed"
obj.save(update_fields=['status'])
return HttpResponseRedirect(reverse('dashboard'))
else:
messages.error(request, 'Error updating your Form')
else:
id = request.GET.get('project_id', '')
obj = get_object_or_404(Leads, project_id=id)
m = obj.__dict__
keys = Leads.objects.get(project_id=m['project_id'])
form_dict = {'project_id':keys.project_id,
'agent':keys.agent,
'client':keys.point_of_contact,
'company':keys.company,
'service':keys.services
}
form = NewDealForm(request.POST or None,initial = form_dict)
return render(request,
"account/close_lead.html",
{'form':form})
models.py
from django.db import models
from django.conf import settings
from django_countries.fields import CountryField
from phone_field import PhoneField
from djmoney.models.fields import MoneyField
from ckeditor.fields import RichTextField
from django.utils import timezone
class Profile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
email = models.EmailField(blank=True,null=True, unique=True)
role = models.TextField(blank=True)
location = models.TextField(blank=True)
photo = models.ImageField(upload_to='users/%Y/%m/%d', blank=True)
def __str__(self):
return self.user.username
class Company(models.Model):
id = models.BigAutoField(primary_key=True)
company = models.CharField(blank=True, max_length=30, unique=True)
def __str__(self):
return self.company
class Client(models.Model):
id = models.BigAutoField(primary_key=True)
firstname = models.CharField(blank=True, max_length=30)
lastname = models.CharField(blank=True, max_length=15)
company = models.ForeignKey(Company, on_delete=models.CASCADE)
position = models.CharField(blank=True, max_length=50)
country = CountryField(blank_label='(select country)')
email = models.EmailField(blank=True, max_length=100, default="this_is#n_example.com", unique=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
phone = PhoneField(default="(XX)-XXX-XXX")
def __str__(self):
return f'{self.firstname} {self.lastname}'
class Leads(models.Model):
CHOICES = (
('Illumination Studies','Illumination Studies'),
('Training','Training'),
('Survey Design','Survey Design'),
('Software License','Software License')
)
STATUS = (('Open','Open'),
('Closed','Closed'),
('Canceled', 'Canceled')
)
project_id = models.BigAutoField(primary_key=True)
company = models.ForeignKey(Company, on_delete=models.CASCADE)
agent = models.ForeignKey(Profile, on_delete=models.CASCADE, default="agent")
created_at = models.DateTimeField(auto_now_add=True)
point_of_contact = models.ForeignKey(Client, on_delete=models.CASCADE)
expected_revenue = MoneyField(max_digits=14, decimal_places=2, default_currency='USD')
expected_licenses = models.IntegerField(blank=True)
country = CountryField(blank_label='(select country)')
status = models.CharField(max_length=10,choices=STATUS)
estimated_closing_date = models.DateField(blank=True)
services = models.CharField(max_length=20,choices=CHOICES)
def __str__(self):
return f'{self.project_id}'
class CallReport(models.Model):
CHOICES = (
('Phone Call','Phone Call'),
('Onsite Meeting', 'Onsite Meeting'),
('Client Offices', "Client Offices"),
('Other Location','Other Location'),
)
id = models.BigAutoField(primary_key=True)
company = models.ForeignKey(Company, on_delete=models.CASCADE)
minutes_of_meeting = RichTextField(blank=True, null=True)
client_POC = models.CharField(max_length=100)
location = models.CharField(max_length=50,choices=CHOICES, default='Phone Call')
title = models.CharField(max_length=100)
date = models.DateField()
ACTeQ_representative = models.ForeignKey(Profile, on_delete=models.CASCADE, default='agent')
def __str__(self):
return f'Call Report for {self.company}, on the {self.date}'
class Deal(models.Model):
CHOICES = (
('Illumination Studies','Illumination Studies'),
('Training','Training'),
('Survey Design','Survey Design'),
('Software License','Software License')
)
project_id = models.ForeignKey(Leads, on_delete=models.CASCADE, default="project_id")
agent = models.ForeignKey(Profile, on_delete=models.CASCADE, default="agent")
service = models.CharField(max_length=20,choices=CHOICES)
closing_date = models.DateField(auto_now_add=True)
client = models.ForeignKey(Client, on_delete=models.CASCADE,default='client')
licenses = models.IntegerField(blank=True)
revenue = MoneyField(max_digits=14, decimal_places=2, default_currency='USD')
comments = models.TextField(blank=True,null=True)
company = models.ForeignKey(Company, on_delete=models.CASCADE)
date = models.DateTimeField(auto_now_add=True)
Lastly, the form:
from .models import Profile, Client, Company, Leads, CallReport, Deal
from django import forms
from django.contrib.auth.models import User
from django.contrib.admin.widgets import AdminDateWidget
from django.forms.fields import DateField
class DateInput(forms.DateInput):
input_type = 'date'
class UserEditForm(forms.ModelForm):
class Meta:
model = User
fields = ('first_name', 'last_name', 'email')
class ProfileEditForm(forms.ModelForm):
class Meta:
model = Profile
fields = ('role', 'photo', 'location')
class ClientForm(forms.ModelForm):
class Meta:
model = Client
fields = ('firstname', 'lastname',"position",'company','country','email','phone')
class CompanyForm(forms.ModelForm):
class Meta:
model = Company
fields = ('company',)
class LeadsForm(forms.ModelForm):
class Meta:
model = Leads
fields = ('project_id','company','agent','point_of_contact','services','expected_licenses',
'expected_revenue','country', 'status', 'estimated_closing_date'
)
widgets = {'estimated_closing_date': DateInput()}
class CallForm(forms.ModelForm):
class Meta:
model = CallReport
fields = ('company','title','location', 'ACTeQ_representative','client_POC','minutes_of_meeting','date')
widgets = {'date':DateInput()}
class DealForm(forms.ModelForm):
class Meta:
model = Deal
fields = ['agent','project_id','service','client', 'licenses','revenue', 'comments']
class EditLeadsForm(forms.ModelForm):
class Meta:
model = Leads
fields = ('project_id','company','agent','point_of_contact','expected_revenue',
'expected_licenses','country', 'status', 'estimated_closing_date',
'services')
widgets = {'date': DateInput()}
class NewDealForm(forms.ModelForm):
class Meta:
model = Deal
fields = ['project_id','agent','client','company','service', 'licenses','revenue', 'comments']
I have already deleted the database and run the migrations, and the error persists.
I have 4 related models and I need to implement the functionality to consistently create instances of these models in a database in one post query. For this I use override of the APIView class post method.
models
class VendorContacts(models.Model):
contact_id = models.AutoField(primary_key=True)
vendor = models.OneToOneField('Vendors', on_delete=models.CASCADE)
contact_name = models.CharField(max_length=45, blank=True)
phone = models.CharField(max_length=45, blank=True)
email = models.CharField(max_length=80, blank=True, unique=True)
class Meta:
db_table = 'vendor_contacts'
class VendorModuleNames(models.Model):
vendor = models.OneToOneField('Vendors', on_delete=models.CASCADE, primary_key=True)
module = models.ForeignKey(Modules, models.DO_NOTHING)
timestamp = models.DateTimeField(auto_now=True)
class Meta:
db_table = 'vendor_module_names'
unique_together = (('vendor', 'module'),)
class Vendors(models.Model):
COUNTRY_CHOICES = tuple(COUNTRIES)
vendorid = models.AutoField(primary_key=True)
vendor_name = models.CharField(max_length=45, unique=True)
country = models.CharField(max_length=45, choices=COUNTRY_CHOICES)
nda = models.DateField(blank=True, null=True)
user_id = models.ForeignKey('c_users.CustomUser', on_delete=models.PROTECT)
timestamp = models.DateTimeField(auto_now_add=True)
class Meta:
db_table = 'vendors'
unique_together = (('vendorid', 'timestamp'),)
class Modules(models.Model):
MODULES_NAME =tuple(MODULES)
mid = models.AutoField(primary_key=True)
module_name = models.CharField(max_length=50, choices=MODULES_NAME)
active = models.BooleanField(default=True)
timestamp = models.DateTimeField(auto_now=True)
class Meta:
db_table = 'modules'
unique_together = (('mid', 'timestamp'),)
serializer.py
class VendorsSerializer(serializers.ModelSerializer):
class Meta:
model = Vendors
fields = ('vendor_name',
'country',
'nda',)
class VendorContactSerializer(serializers.ModelSerializer):
class Meta:
model = VendorContacts
fields = (
'contact_name',
'phone',
'email',)
class VendorModulSerializer(serializers.ModelSerializer):
class Meta:
model = VendorModuleNames
fields = ('module',)
class ModulesSerializer(serializers.ModelSerializer):
class Meta:
model = Modules
fields = ('module_name', )
views.py
class VendorsCreateView(APIView):
"""Create new vendor instances from form"""
def post(self, request, *args, **kwargs):
vendor_serializer = VendorsSerializer(data=request.data)
vendor_contact_serializer = VendorContactSerializer(data=request.data)
vendor_modules_serializer = VendorModulSerializer(data=request.data)
module_serializer = ModulesSerializer(data=request.data)
try:
vendor_serializer.is_valid(raise_exception=True) \
and vendor_contact_serializer.is_valid(raise_exception=True) \
and vendor_modules_serializer.is_valid(raise_exception=True) \
and module_serializer.is_valid(raise_exception=True)
vendor_serializer.save(user_id=request.user)
# ....
# Some new logic here ????
# ...
except ValidationError:
return Response({"errors": (vendor_serializer.errors,
vendor_contact_serializer.errors,
vendor_modules_serializer.errors
)},
status=status.HTTP_400_BAD_REQUEST)
else:
return Response(request.data, status=status.HTTP_200_OK)
There is no problem saving one Vendor model, but I can't imagine how to save cascading all related models in a single request.
save returns the newly saved object, which you can then pass into the subsequent save() methods:
vendor = vendor_serializer.save(user_id=request.user)
module = module_serializer.save()
vendor_module = vendor_modules_serializer.save(module=module, vendor=vendor)
vendor_contact = vendor_contact_serializer.save(vendor=vendor)
I have a created Django-CMS Plugin with a ManytoManyField to another model. When creating the Plugin on the Front-End, i want the user to be able to filter the ManytoManyField list (which might be too long).
By the way this future is already on Django admin:
class ModelAdmin(admin.ModelAdmin):
list_filter = ('field_name', )
form = PartnerLogoTableForm
Is it possible to have something similar like that on my
cms_plugins.py:
class PartnerLogoTablePlugin(CMSPluginBase):
model = LogoTablePlugin
form = LogoTablePluginForm
name = _('LogoTable Plugin')
render_template = False
search_fields = ('description',)
def render(self, context, instance, placeholder):
self.render_template = 'aldryn_logo_tables/plugins/%s/logotable.html' % instance.style
context.update({
'object': instance,
'placeholder': placeholder,
})
return context
plugin_pool.register_plugin(PartnerLogoTablePlugin)
models.py:
class PartnerLogoTable(models.Model):
name = models.CharField(_('Partner name'), max_length=255)
image = FilerImageField(verbose_name=_('Image'), null=True, blank=True, on_delete=models.SET_NULL)
partner_url = models.TextField(_('Partner url'), null=True, blank=True, validators=[URLValidator()])
is_active = models.BooleanField(_('Is active'), blank=True, default=True)
created_at = models.DateTimeField(_('Created at'), auto_now_add=True)
updated_at = models.DateTimeField(_('Updated at'), auto_now=True)
order = models.IntegerField(_('Order'), null=True, blank=True)
class Meta:
verbose_name = _('Partner Logo')
verbose_name_plural = _('Partner Logos')
ordering = ['order']
def __str__(self):
return self.name
class LogoTablePlugin(CMSPlugin):
DEFAULT = 'default'
LOGOTABLE_CHOICES = [
(DEFAULT, _('Default')),
]
description = models.CharField(_('Description'), max_length=255, null=True, blank=True)
partner = models.ManyToManyField(PartnerLogoTable, verbose_name=_('Partner'))
logo_per_row = models.IntegerField(_('Logo per line'), default=1, null=True, blank=True,
validators=[MaxValueValidator(4), MinValueValidator(1)],
help_text=_('Number of logos to be displayed per row'))
style = models.CharField(_('Style'), choices=LOGOTABLE_CHOICES + get_additional_styles(), default=DEFAULT,
max_length=50, blank=True, null=True, )
class Meta:
verbose_name = _('Partner Logo Plugin')
verbose_name_plural = _('Partner Logo Plugins')
def __unicode__(self):
return u'%s' % self.description
forms.py
class LogoTablePluginForm(forms.ModelForm):
model = LogoTablePlugin
def clean_style(self):
.....
return style
class PartnerLogoTableForm(forms.ModelForm):
model = PartnerLogoTable
def clean(self):
....
return self.cleaned_data
This is how the plugin looks now
ModelSelect2Multiple from django-autocomplete-light seems perfect for your use case.
Models.py
from django.db import models
class BusinessType(models.Model):
method = models.CharField(max_length=25)
class Vendor(models.Model):
first_name = models.CharField(max_length=25)
middle_name = models.CharField(max_length=25)
last_name = models.CharField(max_length=25)
nick_name = models.CharField(max_length=10)
email = models.CharField(max_length=30)
company = models.CharField(max_length=25)
phone = models.CharField(max_length=15)
mobile = models.CharField(max_length=10)
fax = models.CharField(max_length=10)
billing_address_street = models.CharField(max_length=120)
billing_address_city = models.CharField(max_length=20)
billing_address_state = models.CharField(max_length=20)
billing_address_zip = models.CharField(max_length=6)
billing_address_country = models.CharField(max_length=20)
shipping_address_street = models.CharField(max_length=120)
shipping_address_city = models.CharField(max_length=20)
shipping_address_state = models.CharField(max_length=20)
shipping_address_zip = models.CharField(max_length=6)
shipping_address_country = models.CharField(max_length=20)
notes = models.CharField(max_length=120)
gstin = models.CharField(max_length=25, null=True)
tin = models.CharField(max_length=25, null=True)
business_type = models.ForeignKey(BusinessType, on_delete=models.CASCADE)
Serializers.py
from rest_framework import serializers
from .models import Vendor,BusinessType
class BusinessTypeSerializer(serializers.HyperlinkedModelSerializer):
[enter image description here][1]
class Meta:
model = BusinessType
fields = ('id','method')
class VendorSerializer(serializers.HyperlinkedModelSerializer):
business_type = serializers.CharField(source='business_type.method')
class Meta:
model = Vendor
fields = ('id','first_name','middle_name','last_name','nick_name','email','company','phone','mobile','fax','billing_address_street','billing_address_city','billing_address_state','billing_address_zip','billing_address_country','shipping_address_street','shipping_address_city','shipping_address_state','shipping_address_zip','shipping_address_country','notes','gstin','tin','business_type')
In Django restframework, foreign key value is not getting in HyperlinkedModelserializer in 'business_type' field. When I tried to post method after declaring foreign key field, it says:
"AssertionError: The .create() method does not support nested
writable fields by default. Write an explicit .create() method for
serializer UserSerializer, or set read_only=True"
I have this simple model and I am having difficult in inserting related field of 'notes' through django rest framework.
class Student(models.Model):
firstName = models.CharField(max_length=100, blank=True, null=True)
lastName = models.CharField(max_length=100, blank=True, null=True)
prefLocation = models.ManyToManyField("Location", blank=True, null=True, related_name = 'prefLocation')
def __unicode__(self):
return self.firstName
class LocationRegion(models.Model):
regionName = models.CharField(max_length=100)
def __unicode__(self):
return self.regionName
class Location(models.Model):
locationName = models.CharField(max_length=100)
region = models.ForeignKey(LocationRegion, null=True, blank=True, related_name='locations')
def __unicode__(self):
return self.locationName
class Note(models.Model):
text = models.CharField(max_length=1000)
student = models.ForeignKey(Student, null=True, blank=True, related_name='notes')
def __unicode__(self):
return self.text
class StudentViewSet(viewsets.ModelViewSet):
queryset = Student.objects.all()
serializer_class = StudentSerializer
I am unsure if I need to use ModelSerializer or generic Serializer. Validated_data doesn't return 'note' field in the deserialized data. I would appreciate any help with the serializer.
Thanks
Here are my serializers :
class StudentSerializer(serializers.ModelSerializer):
def create(self, validated_data):
def get_notes(self, obj):
return validated_data['note']
note = serializers.SerializerMethodField('get_notes')
return Candidate.objects.create(**validated_data)
class Meta:
model = Student
fields = ('id', 'firstName', 'lastName', 'note')
class NoteSerializer(serializers.ModelSerializer):
class Meta:
model = Note