Django form from related model - django

You have models:
class Order(Model):
date = DateField(editable = False, auto_now_add=True)
status = CharField(max_length = 1, choices = STATUS, default = 'N')
profile = ForeignKey(Profile, related_name = 'orders', blank = True, null = True)
shipping = ForeignKey(Shipping, related_name = 'orders', blank = True, null = True)
address = ForeignKey(Address, related_name = 'address_orders', blank = True, null = True)
company = ForeignKey(Company, related_name = 'company_orders', blank = True, null = True)
class Address(Model):
address_profile = ForeignKey(Profile, related_name = 'addresses')
city = CharField(max_length = 256, blank = True, null = True)
street = CharField(max_length = 256, blank = True, null = True)
zipcode = CharField(max_length = 10, blank = True, null = True)
phone = CharField(max_length = 23, blank = True, null = True)
class Company(Address):
company_profile = ForeignKey(Profile, related_name = 'companies')
name = CharField(max_length = 256, blank = True, null = True)
company_id = CharField(max_length = 256, blank = True, null = True)
How do you create OrderForm for specified profile? With this one
class OrderCheckoutForm(forms.ModelForm):
class Meta:
model = Order
I get a form with all addresses and companies in option. I'd like to limit them to related with it's profile. Is there any simple solution?
Thanks in advance,
Etam.

You can feed a queryset to your ModelChoiceField (which is what ModelForms use for ForeignKeys; you can find it in django/forms/models.py). Something like,
class OrderCheckoutForm(forms.ModelForm):
profile = models.ModelChoiceField(queryset = Profile.objects.filter(...))
class Meta:
model = Order
Of course, your filtering criterion will depend on what you are trying to accomplish, which isn't 100% clear from your original post.

Related

Django Testing IntegrityError: duplicate key value violates unique constraint DETAIL: Key (project_id)=(1023044) already exists

I have not been able to resolve this IntegrityError issue in my Django's unittest. Here are my models:
class UserProfile(models.Model):
''' UserProfile to separate authentication and profile '''
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete = models.CASCADE, null = True, blank = True)
# Note: first name and last name is in the custom User model
first_name = models.CharField(max_length = 20, blank = True, null = True)
last_name = models.CharField(max_length = 30, blank = True, null = True)
address = models.CharField(max_length = 100, null=True, blank = True)
address_city = models.CharField(max_length = 30, null = True, blank = True)
metropolitan = models.CharField(max_length = 30, null = True, blank = False)
class Municipality(models.Model):
name = models.CharField(max_length = 50)
abb = models.CharField(max_length = 5)
date_created = models.DateTimeField(auto_now_add = True)
date_modified = models.DateTimeField(auto_now = True)
userprofile = models.ForeignKey('user_profile.UserProfile', blank = False, null = False, related_name = 'userprofile_municipalities', on_delete = models.CASCADE)
class Project(models.Model):
name = models.CharField(max_length = 50)
logo = models.ImageField(null=True, blank = True, width_field = 'logo_width', height_field = 'logo_height')
logo_height = models.IntegerField(default = 40)
logo_width = models.IntegerField(default = 40)
date_created = models.DateTimeField(auto_now_add = True )
date_modified = models.DateTimeField(auto_now = True )
# RELATIONSHIPS:
user_profiles = models.ManyToManyField('user_profile.UserProfile', through = 'ProjectAssociation', through_fields = ('project', 'user_profile' ), blank = True, related_name = 'user_projects')
address = models.OneToOneField(Address, on_delete = models.PROTECT, null = True, blank = True)
municipality = models.ForeignKey('development.Municipality', related_name = 'municipality_projects', null = False, blank = False)
class Job(models.Model):
project = models.OneToOneField('project_profile.Project', blank = False, on_delete = models.CASCADE, related_name = 'job')
...
date_modified = models.DateTimeField(auto_now_add = True)
date_created = models.DateTimeField(auto_now = True)
class Invoice(models.Model):
PO = models.CharField(max_length = 50, blank = False, null = False) # e.g. Mixed Use Residential Commercial Rental Invoice
invoice_type = models.CharField(max_length = 40)
date_created = models.DateTimeField(auto_now = True)
date_modified = models.DateTimeField(auto_now_add = True)
job = models.ForeignKey(DevelopmentProject, related_name = 'job_invoices', blank = True, null = True, on_delete = models.CASCADE)
Invoice_creator = models.ForeignKey('user_profile.UserProfile', related_name = 'created_invoices', blank = True, null = True, on_delete = models.SET_NULL) # ModelForm to enforce If the Invoice creator's account is closed, the corresponding Invoices to be preserved
Invoice_reviewer = models.ForeignKey('user_profile.UserProfile', related_name = 'reviewed_invoices', blank = True, null = True , on_delete = models.SET_NULL ) # The reviewer is not necessary, but
...
In my unittest, I am getting integrity error message even when I try to explicitly assign unique id to the created instance:
class UpdateinvoiceTestCase(TestCase):
''' Unit Test for Updateinvoice View '''
def setUp(self):
self.factory = RequestFactory()
# Create the dependencies
self.userprofile = mommy.make('user_profile.UserProfile')
print ('User profile: ', self.userprofile, ' - userprofile id: ', self.userprofile.id )
self.municipality = mommy.make('development.municipality', userprofile = self.userprofile, _quantity=1)
self.project = mommy.make('project_profile.Project', municipality = self.municipality[0], _quantity=2)
self.job = mommy.make('development.Job', project = self.project[0] )
# Create invoice
self.invoice = mommy.make('development.invoice', job = self.job)
# Passing the pk to create the url
the_uri = reverse('development:update_invoice', args=(self.invoice.pk,))
the_url = 'http://localhost:8000' + reverse('development:update_invoice', args=(self.invoice.pk,))
# Creating a client:
self.response = self.client.get(the_url, follow=True)
def test_url(self):
''' Ensure that the url works '''
self.assertEqual(self.response.status_code, 200)
I have made sure only one test is run using so there is no sharing of the data between different testcases that would throw Django off:
python manage.py test project.tests.test_views.UpdateViewTestCase
I get the the following error message:
IntegrityError: duplicate key value violates unique constraint "development_developmentproject_project_id_key"
DETAIL: Key (project_id)=(1) already exists
I also tried using mommy.make to create project, but I got the same error message. I also tried to specifically assign non-existent ids to the Project creation line, but could not convince Django to stop complaining.
So, Project is being created twice, but I cannot figure out why and where. Any help is much appreciated!
It turned out that I've used signals which created an instance already and I was creating the same instance in my setUpTestData again. The solution was to avoid creating a duplicate instance or simply use get_or_create instead of create or mommy.make

Django Restframework “Got AttributeError when attempting to get a value for field `section_type` on serializer `QuestionSerializer`

This is my model.
class QuestionSection(models.Model):
section = models.CharField(max_length = 100, null = True, blank = True)
max_marks = models.IntegerField()
def __str__(self):
return self.section
class Question(models.Model):
question_section = models.ForeignKey(QuestionSection, on_delete = models.CASCADE, related_name = 'questions')
section_type = models.CharField(max_length = 10,)
questions = models.CharField(max_length = 350, null = True, blank = True)
image = models.CharField(max_length = 10, null = True, blank = True)
no_of_images = models.IntegerField(null = True, blank = True)
marks = models.IntegerField()
shop_view = models.CharField(max_length = 30, null = True, blank = True, choices=(('critical', 'critical'), ('major', 'major')))
what_to_look_for = models.CharField(max_length = 350, null = True, blank = True)
def __str__(self):
return "{}-{}".format(self.section_type, self.marks)
This is my serializer
class QuestionSerializer(serializers.ModelSerializer):
class Meta:
model = Question
fields = '__all__'
class QuestionSectionSerializer(serializers.ModelSerializer):
questions = QuestionSerializer(read_only = True)
class Meta:
model = QuestionSection
fields = '__all__'
I am not able to figuring out how to do it. The API will be like QuestionSection fields and inside that Question fields will be there.

Django Related Field based filter

I have two models based in which one is related to another.
class Contacts(BaseModel):
user = models.ForeignKey(User, related_name='contacts')
group = models.ForeignKey(ContactGroups, related_name = 'contact_list')
name = models.CharField(_("Name"), max_length = 250, null = True, blank = True)
title = models.CharField(_("Title"), max_length = 250, null = True, blank = True)
twitter = models.CharField(_("Twitter"), max_length = 250, null = True, blank = True)
facebook = models.CharField(_("Facebook"), max_length = 250, null = True, blank = True)
google = models.CharField(_("Google +"), max_length=250, null = True, blank = True)
notes = models.TextField(_("Notes"), null = True, blank = True)
image = ImageField(_('mugshot'), upload_to = upload_to, blank = True, null = True)
class PhoneNumbers(BaseModel):
contact = models.ForeignKey(Contacts, related_name='phone_numbers')
phone = models.CharField(_("Phone"), max_length = 200, null = True, blank = True)
type = models.CharField(_("Type"), max_length = 200, choices = TYPES, null = True, blank = True)
Here I wanted filter contacts who have atleast one phonenumber.
I have tried,
contacts = Contacts.objects.filter(user=request.user, phone_numbers__isnull=True)
Is it correct or not? Is there any other optimized method? How can we filter queryset based on related names?
I think you want,
contacts = Contacts.objects.filter(user=request.user, phone_numbers__isnull=False)
i.e check for False rather than True, as you want Contacts where at least one PhoneNumber is there. If its not there it will be NULL.

Either/Or fields in Django models

I was building a django model that has two fields, only one of them is required.
class course_data(models.Model):
link = models.CharField(max_length = 500, null = True, blank = True)
uploaded_file = models.FileField(upload_to='course_files', null = True, blank = True)
name = models.CharField(max_length = 200, null = True, blank = True)
description = models.TextField(null = True, blank = True)
applies_to = models.ManyToManyField('course')
I want the entry to be valid only if the "link" field is provided or if the 'uploaded_file' field is provided or both. I can't make both parameters optional since they can be both left blank. Any suggestions?
This isn't something you'd deal with in the model definition. You would handle it at the form level, by making both fields required=False but checking in the form's clean() method that one of them was supplied.
you can override clean method:
class course_data(models.Model):
link = models.CharField(max_length = 500, null = True, blank = True)
uploaded_file = models.FileField(upload_to='course_files', null = True, blank = True)
name = models.CharField(max_length = 200, null = True, blank = True)
description = models.TextField(null = True, blank = True)
applies_to = models.ManyToManyField('course')
def clean(self):
if self.link == None and self.uploaded_file is None:
raise ValidationError(_('Fields uploaded_file and link required.'))
You can use a ModelForm and override its clean method to get the behaviour you want. If you want to use the admin, you can add the custom behaviour with a ModelAdmin

Join over django models

I want to get the result in one list using three different models in django. How do i apply join over three models.
class CurrentDomainChecks(models.Model):
domain = models.ForeignKey(Domains)
check_type = models.ForeignKey(CheckType)
check_date = models.DateTimeField(auto_now_add = True, primary_key=True)
check_value = models.CharField(_('check value'), max_length = 2048)
check_passed = models.BooleanField(default = False)
class DomainStatus(models.Model):
domain = models.ForeignKey(Domains)
domain_status_date = models.DateTimeField(auto_now_add=True,null = True, blank = True)
domain_status = models.IntegerField(null = True, blank = True)
class Domains(models.Model):
domain_name = models.CharField(_('domain name'), max_length = 255, unique = True)
verified = models.BooleanField(default = False)
user = models.ForeignKey(User)
date_added = models.DateTimeField(auto_now_add=True,null = True, blank = True)
date_last_changed = models.DateTimeField(auto_now=True,null = True, blank = True)
monitoring_frequency = models.CharField(_('monitoring frequency'), max_length = 20,blank = True,null = True)
def __unicode__(self):
return self.domain_name
Did you read this about JOIN ?
Django: implementing JOIN using Django ORM?
"Lookups that span relationships"