I'm attempting to present some serialized data, and am getting a AttributeError when attempting to get a value for field name.
models.py:
class Resource(models.Model):
"""Initial representation of a resource."""
# ID from fixture resources, for internal dedupe
internal_id = models.CharField(max_length=20, null=True, blank=True)
name = models.CharField(max_length=200)
description = models.TextField(null=True, blank=True)
categories = models.ManyToManyField("Category")
neighborhoods = models.ManyToManyField("Neighborhood")
email_contact = models.EmailField(null=True, blank=True)
pdf = models.ManyToManyField("PDF")
phone = models.CharField(max_length=200, blank=True, null=True)
website = models.URLField(max_length=200, blank=True, null=True)
# address
street_address = models.CharField(max_length=400, null=True, blank=True)
city = models.CharField(max_length=100, null=True, blank=True)
state = models.CharField(max_length=10, null=True, blank=True)
latitude = models.FloatField(null=True, blank=True)
longitude = models.FloatField(null=True, blank=True)
zip_code = models.CharField(max_length=10, null=True, blank=True)
# meta
created_at = models.DateTimeField(auto_now_add=True)
modified_at = models.DateTimeField(auto_now=True)
def __str__(self):
return self.name
def __unicode__(self):
return u'{}'.format(self.name)
#property
def categories_str(self):
return [str(t) for t in self.categories.all()]
#property
def neighborhoods_str(self):
return [str(t) for t in self.neighborhoods.all() if t] or ["Houston"]
#property
def bookmark(self):
"""This is here to make it easier to serialize a standard resource."""
return getattr(self, "_bookmark", None)
#bookmark.setter
def bookmark(self, bookmark):
self._bookmark = bookmark
def indexing(self):
safe_zip = str(self.zip_code or "")
safe_neighborhood = [n for n in self.neighborhoods.all() if n] or ["Houston"]
obj = ResourceDoc(
meta={"id": self.id},
name=self.name,
resource_suggest=self.name,
email_contact=self.email_contact,
phone=self.phone,
description=self.description,
website=self.website,
categories=self.categories_str,
street_address=self.street_address,
city=self.city,
state=self.state,
zip_code=safe_zip,
neighborhoods=self.neighborhoods_str,
# TODO default to Houston for now but need a way to handle case where we don't know neighborhood or zip code
location_suggest=[str(attr) for attr in chain([safe_zip], safe_neighborhood) if attr],
created_at=self.created_at,
modified_at=self.modified_at,
)
if self.latitude and self.longitude:
obj.geo_coords = {
"lat": str(self.latitude),
"lon": str(self.longitude),
}
obj.save(index="welnity_production_2")
return obj.to_dict(include_meta=True)
serializers.py:
class ResourceSerializer(serializers.ModelSerializer):
bookmark = BookmarkMetaSerializer(read_only=True)
notes = PrivateNoteSerializer(read_only=True, many=True)
categories = CategorySerializer(read_only=True, many=True)
neighborhoods = NeighborhoodSerializer(read_only=True, many=True)
class Meta:
model = Resource
fields = '__all__'
view.py:
class BookmarkGroupView(View):
def get(self, request, *args, **kwargs):
# resources = Resource.objects.filter(bookmarks__user=request.user)
# resources = get_enriched_resources(request.user, resources)
group = BookmarkGroup.objects.get(name='food')
resources = group.bookmarks.all()
serialized = ResourceSerializer(resources, many=True)
context = {
"component": "groups.js",
"props": {
"resources": JSONRenderer().render(serialized.data)
}
}
return render(request, "groups.html", context)
the error is
Got AttributeError when attempting to get a value for field `name` on serializer `ResourceSerializer`.
The serializer field might be named incorrectly and not match any attribute or key on the `Bookmark` instance.
Original exception text was: 'Bookmark' object has no attribute 'name'.
any help or direction would be much appreciated!
You are giving your ResourceSerializer the wrong model instances.
resources = group.bookmarks.all()
serialized = ResourceSerializer(resources, many=True)
Here you are telling your serializer to use group.bookmarks.all() as data source which are instances of Bookmark, not Resource.
Related
I am trying to implement Q search on my APIView, but it says invalid lookups name which is strange. I have added the search fields according to the fields of the models.
My view:
from django.db.models import Q
class PrdouctSearchAPIView(ListAPIView):
permission_classes = [AllowAny]
# def list(self, request, *args, **kwargs):
def get(self, request, *args, **kwargs):
qur = self.request.query_params.get('search')
item = Product.objects.filter(Q(category__name__icontains=qur)|
Q(brand__name__icontains=qur)|
Q(description__icontains=qur)|
Q(collection__name__icontains=qur)|
Q(variants__name__icontains=qur))
serializer = ProductSerializer(item,many=True)
return Response(serializer.data)
My models:
class Product(models.Model):
merchant = models.ForeignKey(Seller,on_delete=models.CASCADE,blank=True,null=True)
category = models.ManyToManyField(Category, blank=False)
sub_category = models.ForeignKey(Subcategory, on_delete=models.CASCADE,blank=True,null=True)
brand = models.ForeignKey(Brand, on_delete=models.CASCADE)
collection = models.ForeignKey(Collection, on_delete=models.CASCADE)
featured = models.BooleanField(default=False) # is product featured?
description = RichTextField(blank=True)
variants = models.ManyToManyField(Variants,related_name='products')
class Category(models.Model):
#parent = models.ForeignKey('self',related_name='children',on_delete=models.CASCADE,blank=True,null=True)
name = models.CharField(max_length=100, unique=True)
image = models.ImageField(null=True, blank=True)
class Brand(models.Model):
brand_category = models.ManyToManyField(Category,blank=True,null=True)
name = models.CharField(max_length=100, unique=True)
class Collection(models.Model):
name = models.CharField(max_length=100, unique=True)
image = models.ImageField(null=True, blank=True)
My url is :
path('api/productsearch',views.PrdouctSearchAPIView.as_view(),name='api-productsearch'),
As we can see there are fields "category__name" and such not only "name", but the error says invalid lookup "name".
I am using DRF for creating the CRUD APIs and have to deal with multiple databases (having same schema) depending on the request.
models.py
class CustomerMaster(models.Model):
customer_key = models.IntegerField(db_column='CUSTOMER_KEY', primary_key=True) # Field name made lowercase.
first_name = models.TextField(db_column='FIRST_NAME', blank=True, null=True) # Field name made lowercase.
last_name = models.TextField(db_column='LAST_NAME', blank=True, null=True) # Field name made lowercase.
email = models.CharField(db_column='EMAIL', max_length=255, blank=True, null=True) # Field name made lowercase.
gender = models.TextField(db_column='GENDER', blank=True, null=True) # Field name made lowercase.
dob = models.DateField(db_column='DOB', blank=True, null=True) # Field name made lowercase.
phone = models.CharField(db_column='PHONE', max_length=255, blank=True, null=True) # Field name made lowercase.
address = models.TextField(db_column='ADDRESS', blank=True, null=True) # Field name made lowercase.
...
class Meta:
db_table = 'customer_master'
def __str__(self):
return self.first_name + self.last_name
class Folder(models.Model):
name = models.CharField(max_length=100)
sib_id = models.IntegerField(unique=True, null=True)
def __str__(self):
return self.name
class Segment(models.Model):
name = models.CharField(max_length=100)
folder = models.ForeignKey(Folder, on_delete=models.CASCADE, null=True)
selection = JSONField()
createdAt = models.DateTimeField(auto_now_add=True)
updatedAt = models.DateTimeField(auto_now=True)
createdBy = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
contact = models.ManyToManyField(CustomerMaster)
sib_id = models.IntegerField(unique=True, null=True)
def __str__(self):
return self.name
serializers.py
class SegmentSerializer(serializers.ModelSerializer):
contact = serializers.SlugRelatedField(many=True, queryset=CustomerMaster.objects.all(), slug_field='email')
createdBy = UserSerializer(required=False)
class Meta:
model = Segment
fields = ('id', 'name', 'folder', 'selection', 'createdAt', 'updatedAt', 'createdBy', 'contact', 'sib_id')
def create(self, validated_data):
club = self.context['club']
contact_data = validated_data.pop('contact')
segment = Segment.objects.using(club).create(**validated_data)
segment.contact.add(*contact_data)
return segment
def update(self, instance, validated_data):
club = self.context['club']
instance.contact.clear()
contact_data = validated_data.pop('contact')
instance.name = validated_data.get('name', instance.name)
instance.folder = validated_data.get('folder', instance.folder)
instance.selection = validated_data.get('selection', instance.selection)
instance.save(using=club)
instance.contact.add(*contact_data)
return instance
views.py
class SegmentList(generics.ListCreateAPIView):
serializer_class = SegmentSerializer
def get_queryset(self):
club = self.kwargs['club']
return Segment.objects.using(club).all()
def post(self, request, club, format=None):
serializer = SegmentSerializer(data=request.data, context={'club': club})
if serializer.is_valid():
folder = get_object_or_404(Folder.objects.using(club).all(), pk=int(request.data["folder"]))
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
Here in my Segment model, folder is a foreign key referencing to Folder model. I need to use the database based on the request url and all the databases have same schemas. The GET request works fine. However, for the POST and PUT requests, DRF checks the foreign key constraint of folder in the default database.
For example
POST Request:
{
"name": "Testing",
"folder": 8,
"selection": "{'testing': 20}",
"contact": []
}
It is giving me the following response:
{
"folder": [
"Invalid pk \"8\" - object does not exist."
]
}
But the folder with pk "8" exists in the intended database.
I am using python 3.7, django 2.2.11, django rest framework 3.11.0
Any help would be appreciated. Thanks in advance!
I've two model. I would like to save data from ForeignKey model. I'm created a modelform and save with my main foreignkey model. But I got this error ValueError at /c/customer/1/
Cannot assign "'1'": "BillingData.customer" must be a "CustomerData" instance.
I created Django model form and hocked up with view.
models.py file
class CustomerData(models.Model):
customer_name = models.CharField(max_length=100)
customer_no = models.CharField(max_length=100, default='', blank=True)
mobile_number = models.IntegerField()
alternative_phone = models.IntegerField(null=True, blank=True)
union_name = models.ForeignKey(UnionName, on_delete=models.SET_NULL, null=True)
word_name = models.ForeignKey(UnionWordName, on_delete=models.SET_NULL, null=True)
full_address = models.CharField(max_length=200, null=True, blank=True)
create_date = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
def __str__(self):
return '%s, Mobile: %s' % (self.customer_name, self.mobile_number)
def get_absolute_url(self):
return reverse('customer_data', kwargs={'pk': self.pk})
class BillingData(models.Model):
bill_no = models.CharField(max_length=100, default='', blank=True)
customer = models.ForeignKey(CustomerData, on_delete=models.CASCADE)
sales_person = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.SET_NULL, null=True)
customer_money = models.IntegerField()
create_date = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
def __str__(self):
return '%s %s' % (self.customer.customer_name, self.create_date.date())
def get_absolute_url(self):
return reverse('customers.views.BillingPage', kwargs={'pk': self.pk})
forms.py file
class BillCreateForms(forms.ModelForm):
bill_no = forms.CharField(max_length=100)
customer = forms.ChoiceField(choices=[(x.id, x.customer_name) for x in CustomerData.objects.all()])
customer_money = forms.IntegerField()
def save(self, commit=True):
instance = super(BillCreateForms, self).save(commit=False)
customer_pk = self.cleaned_data['customer']
instance.customer = CustomerData.objects.get(pk=customer_pk)
instance.save(commit)
return instance
class Meta:
model = BillingData
fields = ('bill_no', 'customer', 'customer_money',)
views.py file
class CustomerDataView(FormMixin, generic.DetailView):
model = CustomerData
form_class = BillCreateForms
template_name = "customers/customerdata_detail.html"
print(form_class)
success_url = '/c/'
def post(self, request, *args, **kwargs):
if not request.user.is_authenticated:
return HttpResponseForbidden()
form = self.get_form()
if form.is_valid():
return self.form_valid(form)
else:
return self.form_invalid(form)
I expect data save with foreignkey relation data. But doesn't save here.
You can't fix this problem in the save method, because the error happens before it gets that far.
You should be using a ModelChoiceField, not a ChoiceField. Not only would this fix the problem, it would also let you remove your entire save method.
customer = forms.ModelChoiceField(queryset=CustomerData.objects.all())
Change this line
instance.customer = CustomerData.objects.get(pk=customer_pk)
to
instance.customer_id = CustomerData.objects.get(pk=customer_pk).pk
Model:
class Blog(models.Model):
# ...
pass
class Entry(models.Model):
blog = models.ForeignKey(Blog, on_delete=models.CASCADE, null=True)
Set object
b = Blog.objects.get(id=1)
e = Entry.objects.get(id=234)
b.entry_set.add(e)
I have a profile model which contains experience and education as foreign key fields.
When I access profile template, it throws.
I tried post_save,
def create_education(sender, instance, created, **kwargs):
if created:
Profile.objects.create(education=instance)
post_save.connect(create_education, sender=CustomUser)
it throws this error,
How do I define a post_save signal so experience and education are created when I create a profile?
Note: I double checked the error is because foreign fields are empty i.e there is no error when I add experience and education fields in django admin.
models.py
class Work_Experience(models.Model):
job_title = models.CharField(max_length=100, null=True, blank=True)
company = models.CharField(max_length=100, null=True, blank=True)
description = models.CharField(max_length=300, null=True, blank=True)
exp_start_date = models.DateField(null=True, blank=True)
exp_end_date = models.DateField(null=True, blank=True)
class Education(models.Model):
degree = models.CharField(max_length=100, null=True, blank=True)
school = models.CharField(max_length=100, null=True, blank=True)
edu_start_date = models.DateField(null=True, blank=True)
edu_end_date = models.DateField(null=True, blank=True)
class Profile(models.Model):
experience = models.ForeignKey(Work_Experience, on_delete=models.SET_NULL, null=True, blank=True)
education = models.ForeignKey(Education, on_delete=models.SET_NULL, null=True, blank=True)
forms.py
class ProfileSettingsForm(forms.ModelForm):
job_title = forms.CharField(max_length=40, required=False)
company = forms.CharField(max_length=40, required=False)
description = forms.CharField(max_length=40, required=False)
exp_start_date = forms.DateField(required=False)
exp_end_date = forms.DateField(required=False)
degree = forms.CharField(max_length=40, required=False)
school = forms.CharField(max_length=40, required=False)
edu_start_date = forms.DateField(required=False, input_formats=settings.DATE_INPUT_FORMATS)
edu_end_date = forms.DateField(required=False, input_formats=settings.DATE_INPUT_FORMATS)
def __init__(self, *args, **kwargs):
instance = kwargs.get('instance', None)
super(ProfileSettingsForm, self).__init__(*args, **kwargs)
self.fields['job_title'].initial = self.instance.experience.job_title
self.fields['company'].initial = self.instance.experience.company
self.fields['description'].initial = self.instance.experience.description
self.fields['exp_start_date'].initial = self.instance.experience.exp_start_date
self.fields['exp_end_date'].initial = self.instance.experience.exp_end_date
self.fields['degree'].initial = self.instance.education.degree
self.fields['school'].initial = self.instance.education.school
self.fields['edu_start_date'].initial = self.instance.education.edu_start_date
self.fields['edu_end_date'].initial = self.instance.education.edu_end_date
def save(self, commit=True):
model = super(ProfileSettingsForm, self).save(commit=False)
jt = self.cleaned_data['job_title']
co = self.cleaned_data['company']
desc = self.cleaned_data['description']
esd = self.cleaned_data['exp_start_date']
eed = self.cleaned_data['exp_end_date']
degree = self.cleaned_data['degree']
school = self.cleaned_data['school']
edusd = self.cleaned_data['edu_start_date']
edued = self.cleaned_data['edu_end_date']
if model.experience:
model.experience.job_title = jt
model.experience.company = co
model.experience.description = desc
model.experience.exp_start_date = esd
model.experience.exp_end_date = eed
model.experience.save()
else:
model.experience = Work_Experience.objects.create(job_title=jt,
company=co,
description=desc,
exp_start_date=esd,
exp_end_date=eed)
if model.education:
model.education.degree = degree
model.education.school = school
model.education.edu_start_date = edusd
model.education.edu_end_date = edued
model.education.save()
else:
model.education = Education.objects.create(degree=degree,
school=school,
edu_start_date=edusd,
edu_end_date=edued)
if commit:
model.save()
return model
Views.py
class ProfileSettingsView(UpdateView):
model = Profile
form_class = ProfileSettingsForm
pk_url_kwarg = 'pk'
context_object_name = 'object'
template_name = 'profile_settings.html'
def get_success_url(self):
return reverse_lazy('users:profile_settings', args = (self.object.id,))
UPDATE
If I remove the init() method in form, the error resolves. But I don't get the values from database in the form fields once I save it.
How can I rewrite init() method?
def __init__(self, *args, **kwargs):
instance = kwargs.get('instance', None)
super(ProfileSettingsForm, self).__init__(*args, **kwargs)
self.fields['job_title'].initial = self.instance.experience.job_title
self.fields['company'].initial = self.instance.experience.company
self.fields['description'].initial = self.instance.experience.description
self.fields['exp_start_date'].initial = self.instance.experience.exp_start_date
self.fields['exp_end_date'].initial = self.instance.experience.exp_end_date
self.fields['degree'].initial = self.instance.education.degree
self.fields['school'].initial = self.instance.education.school
self.fields['edu_start_date'].initial = self.instance.education.edu_start_date
self.fields['edu_end_date'].initial = self.instance.education.edu_end_date
Why the error?
In the line:
self.fields['job_title'].initial = self.instance.experience.job_title
you're dealing with a Profile instance that does not have a related experience.
How do I define a post_save signal so experience and education are created when I create a profile?
If you want every time you create a Profile it gets populated with am experience and education you should have a signal like:
def create_profile(sender, instance, created, **kwargs):
if created:
experience = Work_Experience.objects.create(profile=instance)
education = Education.objects.create(profile=instance)
post_save.connect(create_profile, sender=Profile)
Why the post_save signal is not triggered when calling the save() of the form?
model = super(ProfileSettingsForm, self).save(commit=False)
According the docs:
This save() method accepts an optional commit keyword argument, which accepts either True or False. If you call save() with commit=False, then it will return an object that hasn’t yet been saved to the database. In this case, it’s up to you to call save() on the resulting model instance. This is useful if you want to do custom processing on the object before saving it, or if you want to use one of the specialized model saving options. commit is True by default.
So by the time you do:
model.experience.job_title = jt
your post_save signal hasn't been triggered and therefore model.experience remains None hence the error:
'NoneType' object has no attribute job_title.
You cannot do that,i recommend you read django docs. just Do this:
Update here
The code bellow work as expected..
from django.conf import settings
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.contrib.auth.base_user import AbstractBaseUser
from latiro_app.managers import UserManager
class User(AbstractBaseUser):
email = models.CharField(verbose_name='email or phone number ', max_length=50, unique=True )
first_name = models.CharField('first name', max_length=15,blank=True)
last_name = models.CharField('last name', max_length=15,blank=True)
country = CountryField(blank=True)
date_joined = models.DateTimeField('date joined', auto_now_add=True)
slug = models.SlugField('slug', max_length=50, unique=True, null=True)
is_active = models.BooleanField('active',default=False)
is_staff = models.BooleanField('staff', default=False)
email_confirmed = models.BooleanField(default=False)
objects = UserManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = []
class Meta:
db_table = "users"
permissions = (
("edit_user", "Edit User"),
)
class WorkExperience(models.Model):
job_title = models.CharField(max_length=100, null=True, blank=True)
company = models.CharField(max_length=100, null=True, blank=True)
description = models.CharField(max_length=300, null=True, blank=True)
exp_start_date = models.DateField(null=True, blank=True)
exp_end_date = models.DateField(null=True, blank=True)
class Meta:
db_table = "experience"
def __str__(self):
return (self.job_title)
class Education(models.Model):
degree = models.CharField(max_length=100, null=True, blank=True)
school = models.CharField(max_length=100, null=True, blank=True)
edu_start_date = models.DateField(null=True, blank=True)
edu_end_date = models.DateField(null=True, blank=True)
class Meta:
db_table = "education"
def __str__(self):
return (self.degree)
class Profile (models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete= models.CASCADE,
verbose_name='list of users', null=True)
experience = models.ForeignKey(WorkExperience, on_delete=models.SET_NULL, null=True, blank=True)
education = models.ForeignKey(Education, on_delete=models.SET_NULL, null=True, blank=True)
def __str__(self):
return (self.user)
class Meta:
db_table = "profile"
#receiver(post_save, sender=settings.AUTH_USER_MODEL)
def create_profile(sender, instance, created, **kwargs):
if created and not kwargs.get('raw', False):
profile = Profile(user=instance)
profile.save()
This should work. Tested on my database:
+----+--------------+---------------+---------+
| id | education_id | experience_id | user_id |
+----+--------------+---------------+---------+
| 1 | NULL | NULL | 2 |
+----+--------------+---------------+---------+
The null values on education_id and experience_id will be update by user_id instance when updating profile.
Now User can update his/her profile like this:
note:i'm not using signal.
#Form.py
class EducationForm(forms.ModelForm):
degree = forms.CharField(max_length=40, required=False)
school = forms.CharField(max_length=40, required=False)
edu_start_date = forms.DateField(required=False,
input_formats=settings.DATE_INPUT_FORMATS)
edu_end_date = forms.DateField(required=False,
input_formats=settings.DATE_INPUT_FORMATS)
class Meta:
model= Education
fields =["degree","school", "edu_start_date","edu_start_date"]
#View.py
class EducationFormView(UpdateView):
model = Education
form_class = EducationForm
template_name = 'latiro_app/education_form.html'
def get_success_url(self):
return reverse_lazy('users:profile_settings',
args =(self.object.id,))
def get(self, form, ** kwargs):
profile_instance = get_object_or_404(self.model, user_id=self.kwargs['pk'])
#Pass user profile data to the form
context = {'form':self.form_class(instance=profile_instance)}
if self.request.is_ajax():
kwargs['ajax_form'] = render_to_string(self.template_name, context, request=self.request )
return JsonResponse(kwargs)
else:
return render(self.request, self.template_name, context)
I have a Django 'add business' view which adds a new business with an inline 'business_contact' form.
The form works fine, but I'm wondering how to write up the unit test - specifically, the 'postdata' to send to self.client.post(settings.BUSINESS_ADD_URL, postdata)
I've inspected the fields in my browser and tried adding post data with corresponding names, but I still get a 'ManagementForm data is missing or has been tampered with' error when run.
Anyone know of any resources for figuring out how to post inline data?
Relevant models, views & forms below if it helps. Lotsa thanks.
MODEL:
class Contact(models.Model):
""" Contact details for the representatives of each business """
first_name = models.CharField(max_length=200)
surname = models.CharField(max_length=200)
business = models.ForeignKey('Business')
slug = models.SlugField(max_length=150, unique=True, help_text=settings.SLUG_HELPER_TEXT)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
phone = models.CharField(max_length=100, null=True, blank=True)
mobile_phone = models.CharField(max_length=100, null=True, blank=True)
email = models.EmailField(null=True)
deleted = models.BooleanField(default=False)
class Meta:
db_table='business_contact'
def __unicode__(self):
return '%s %s' % (self.first_name, self.surname)
#models.permalink
def get_absolute_url(self):
return('business_contact', (), {'contact_slug': self.slug })
class Business(models.Model):
""" The business clients who you are selling products/services to """
business = models.CharField(max_length=255, unique=True)
slug = models.SlugField(max_length=100, unique=True, help_text=settings.SLUG_HELPER_TEXT)
description = models.TextField(null=True, blank=True)
primary_contact = models.ForeignKey('Contact', null=True, blank=True, related_name='primary_contact')
business_type = models.ForeignKey('BusinessType')
deleted = models.BooleanField(default=False)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
address_1 = models.CharField(max_length=255, null=True, blank=True)
address_2 = models.CharField(max_length=255, null=True, blank=True)
suburb = models.CharField(max_length=255, null=True, blank=True)
city = models.CharField(max_length=255, null=True, blank=True)
state = models.CharField(max_length=255, null=True, blank=True)
country = models.CharField(max_length=255, null=True, blank=True)
phone = models.CharField(max_length=40, null=True, blank=True)
website = models.URLField(null=True, blank=True)
class Meta:
db_table = 'business'
def __unicode__(self):
return self.business
def get_absolute_url(self):
return '%s%s/' % (settings.BUSINESS_URL, self.slug)
VIEWS:
def business_add(request):
template_name = 'business/business_add.html'
if request.method == 'POST':
form = AddBusinessForm(request.POST)
if form.is_valid():
business = form.save(commit=False)
contact_formset = AddBusinessFormSet(request.POST, instance=business)
if contact_formset.is_valid():
business.save()
contact_formset.save()
contact = Contact.objects.get(id=business.id)
business.primary_contact = contact
business.save()
#return HttpResponse(help(contact))
#business.primary = contact.id
return HttpResponseRedirect(settings.BUSINESS_URL)
else:
contact_formset = AddBusinessFormSet(request.POST)
else:
form = AddBusinessForm()
contact_formset = AddBusinessFormSet(instance=Business())
return render_to_response(
template_name,
{
'form': form,
'contact_formset': contact_formset,
},
context_instance=RequestContext(request)
)
FORMS:
class AddBusinessForm(ModelForm):
class Meta:
model = Business
exclude = ['deleted','primary_contact',]
class ContactForm(ModelForm):
class Meta:
model = Contact
exclude = ['deleted',]
AddBusinessFormSet = inlineformset_factory(Business,
Contact,
can_delete=False,
extra=1,
form=AddBusinessForm,
)
The problem is you have not included the management form in your data. You need to include form-TOTAL_FORMS (total number of forms in the formset, default is 2), form-INITIAL_FORMS (the initial number of forms in the formset, default is 0) and form-MAX_NUM_FORMS (the maximum number of forms in the formset, default is '').
See the Formset documentation for more information on the management form.