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.
Related
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
Do you have any idea how to opitimize (time) this query? It is so slow even if wordpress population is around 1000.
query:
al = Wordpress.objects.all().order_by('?')
zaplecza = Wordpress.objects.none()
for l in labels.split(","):
zaplecza = zaplecza | al.filter(label = l)
zaplecza = zaplecza.exclude(wordpress__url = project_name) <--very slow
models.py
class Wordpress(models.Model):
url = models.CharField(max_length = 1000)
login = models.CharField(max_length = 1000, default = "admin")
password = models.CharField(max_length = 1000, default = "perkoz")
label = models.CharField(max_length = 1000)
cms = models.CharField(max_length = 1000)
class Project(models.Model):
url = models.CharField(max_length = 1000)
links = models.TextField(blank = True, null = True, verbose_name = "Linki do wpisów")
wordpress = models.ManyToManyField(Wordpress, related_name = "wordpress", verbose_name = "Dodane do zaplecz")
main_link = models.CharField(max_length = 1000)
dir_links = models.TextField(blank = True, null = True, verbose_name="Anchory")
blog_links = models.TextField(blank = True, null = True, verbose_name="Lista linków i anchorów z ;;;")
category = models.ForeignKey(Category, related_name = "projekt")
kategorie = models.CharField(max_length = 1000)
labels = models.CharField(max_length = 1000)
tagi = models.CharField(max_length = 1000)
auto_tekst = models.BooleanField(verbose_name="Auto tekst")
arts = models.TextField(blank = True, null = True, verbose_name="Artykuły")
title = models.TextField(blank = True, null = True, verbose_name="Tytuł")
no = models.IntegerField(blank = True, null = True, verbose_name="Liczba wpisów")
last_added = models.DateTimeField(blank = True, null = True, verbose_name="Ostatnio dodane")
You're fetching m2m related objects, so you should use prefetch_related in your query to optimize it.
https://docs.djangoproject.com/en/dev/ref/models/querysets/#django.db.models.query.QuerySet.prefetch_related
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
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"
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.