I have two models in different apps: Program in programs and Contact in contacts. Each program can have many contacts. I want to have a field in Program called database_quantity that shows how many contacts are associated with that program. Here is what I have tried so far which is giving me this error: ImportError: cannot import name 'Contact'. I think this has to do with circular referencing but I am lost with how to proceed.
programs models.py
from django.db import models
from django.utils import timezone
from django.contrib.auth.models import User
from contacts.models import Contact
class Program(models.Model):
program_code = models.CharField(max_length=6)
program_format = models.ForeignKey(ProgramFormat, models.SET_NULL, blank=True, null=True)
program_type = models.ForeignKey(ProgramType, models.SET_NULL, blank=True, null=True)
program_board = models.ForeignKey(RealEstateBoard, models.SET_NULL, blank=True, null=True)
article_content_type = models.ForeignKey(ArticleContentType, models.SET_NULL, blank=True, null=True)
program_name = models.CharField(max_length=60)
date_created = models.DateTimeField(default=timezone.now)
client = models.ForeignKey(User, on_delete=models.CASCADE)
def get_database_quantity(self):
database_quantity = Contact.objects.all().filter(Contact.author=Program.client)
return database_quantity
database_quantity = property(get_database_quantity)
contacts models.py
from django.db import models
from django.utils import timezone
from django.contrib.auth.models import User
from django.urls import reverse
from programs.models import Program
class Contact(models.Model):
first_name1 = models.CharField(max_length=100, verbose_name='First Name')
last_name1 = models.CharField(max_length=100, verbose_name='Last Name', blank=True)
date_posted = models.DateTimeField(default=timezone.now)
author = models.ForeignKey(User, on_delete=models.CASCADE)
active_status = models.BooleanField(default=True)
program_code = models.ForeignKey(Program, on_delete=models.DO_NOTHING, null=True, blank=True)
Settings Installed Apps
INSTALLED_APPS = [
'blog.apps.BlogConfig',
'users.apps.UsersConfig',
'contacts.apps.ContactsConfig',
'programs.apps.ProgramsConfig',
'crispy_forms',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'import_export',
]
contacts apps.py
from django.apps import AppConfig
class ContactsConfig(AppConfig):
name = 'contacts'
1- You can define your ForeignKey mappings with strings instead of Model references, like this:
program_code = models.ForeignKey('programs.Program', on_delete=models.DO_NOTHING, null=True, blank=True)
So that you won't need to import a model from another app into models.py
2 - You have several problems in your get_database_quantity method, you need to filter with model instance, not model Class, i.e self.client instead of Program.client. Also you shouldn't filter like Contact.author=..., it should be like author=.... And, to get quantity, you need .count() method of querysets. Finally, you can import other model locally to avoid circular import issues.
def get_database_quantity(self):
from contacts.models import Contact
database_quantity = Contact.objects.filter(author=self.client).count()
return database_quantity
3 - You can also write get_database_quantity like this:
def get_database_quantity(self):
return self.client.contacts.count()
If you define your related ForeignKey field like this:
author = models.ForeignKey(User, on_delete=models.CASCADE, related_name='contacts')
Related
I am trying to make a model that stores favorite shows for users, and I have been using viewsets. I have a users and shows viewset that work just like I expect them to, and I have another model that simply stores relationships between users and shows. When I add that as a viewset though, I get the id, and user, and I don't get a show.
Here are the results for the favorites:
[
{
"id":2,
"user":{
"username":"poduck",
"first_name":"",
"last_name":"",
"email":"poduck#gmail.com",
"image":null,
"url":"http://0.0.0.0:8000/api/users/poduck/?format=json"
}
}
]
There isn't even a show field. It's not like the data isn't there either. I have been able to use queries on the data with no trouble. I have access to both the show and the user from the favorite.
I thought that maybe that the fact that the show points to a user, and the favorite points to a user that there may be some circular conflict there, but beyond excluding the user field from the Show serializer, I don't know what to do to fix that, and yes, I did try excluding it from the Show serializer.
shows.models:
from django.db import models
from django.utils.translation import gettext_lazy as _
from localflavor.us.models import USStateField, USZipCodeField
from users.models import User
from phonenumber_field.modelfields import PhoneNumberField
# Create your models here.
class Show(models.Model):
# Information
title = models.CharField(_("Title"), blank=False, max_length=255)
location = models.CharField(_("Location Name"), blank=False, max_length=255)
image = models.ImageField(upload_to='show_images', blank=True)
description = models.TextField(_("Description"), blank=False)
start_date = models.DateField(_("Start Date"), blank=False)
end_date = models.DateField(_("End Date"), blank=False)
registration_start = models.TimeField(_("Registration Start Time"), blank=False)
registration_end = models.TimeField(_("Registration End Time"), blank=False)
start_time = models.TimeField(_("Spectator Start Time"), blank=False)
end_time = models.TimeField(_("Spectator End Time"))
address = models.CharField(_("Show Address"), blank=False, max_length=255)
city = models.CharField(_("City"), blank=False, max_length=255)
state = USStateField(_("State"), blank=False, max_length=2)
zip = USZipCodeField(_("Zip Code"), blank=False)
contact_name = models.CharField(_("Contact name"), blank=True, max_length=255)
contact_email = models.EmailField(_("Contact Email"), blank=True, max_length=255)
contact_phone = PhoneNumberField(_("Contact Phone"), blank=True)
website = models.URLField(_('Official website'), blank=True)
entry_fee = models.DecimalField(_('Entry fee'), default=0.00, blank=False, decimal_places=2, max_digits=10)
spectator_entry_fee = models.DecimalField(_('Spectator entry fee'), default=0.00, blank=False, decimal_places=2, max_digits=10)
trophies = models.BooleanField(_("Trophies or Ribbons Awarded"), default=False)
dash_plaques = models.BooleanField(_("Dash Plaques Given"), default=False)
dash_plaque_quantity = models.IntegerField(_("Quantity of dash plaques to be given"), null=True, blank=True)
door_prizes = models.BooleanField(_("Door Prizes"), default=False)
judging = models.BooleanField(_("Professional Judging"), default=False)
user = models.ForeignKey(User, on_delete=models.CASCADE)
created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
def __str__(self):
return f"{self.title}"
class Favorite(models.Model):
show = models.ForeignKey(Show, on_delete=models.CASCADE)
user = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self):
return f"{self.show.title}"
shows.api.serializers:
from rest_framework import serializers
from shows.models import Show, Favorite
from users.api.serializers import UserSerializer
class ShowSerializer(serializers.ModelSerializer):
user = UserSerializer()
class Meta:
model = Show
fields = '__all__'
class FavoriteSerializer(serializers.ModelSerializer):
show = ShowSerializer(many=True, read_only=True)
user = UserSerializer()
class Meta:
model = Favorite
fields = '__all__'
shows.api.viewsets:
from car_show_helper.shows.models import Show
from .serializers import ShowSerializer, FavoriteSerializer
from rest_framework import viewsets
class ShowViewSet(viewsets.ModelViewSet):
queryset = Show.objects.all()
serializer_class = ShowSerializer
class FavoriteViewSet(viewsets.ModelViewSet):
queryset = Show.objects.all()
serializer_class = FavoriteSerializer
And finally the api_router:
from django.conf import settings
from rest_framework.routers import DefaultRouter, SimpleRouter
from car_show_helper.users.api.views import UserViewSet
from car_show_helper.shows.api.viewsets import ShowViewSet, FavoriteViewSet
if settings.DEBUG:
router = DefaultRouter()
else:
router = SimpleRouter()
router.register("users", UserViewSet)
router.register("shows", ShowViewSet, basename="shows")
router.register("favorites", FavoriteViewSet, basename="favorites")
app_name = "api"
urlpatterns = router.urls
Any help would be appreciated.
First, change queryset inside FavoriteViewSet
class FavoriteViewSet(viewsets.ModelViewSet):
queryset = Show.objects.all()
serializer_class = FavoriteSerializer
to
queryset = Favorite.objects.all()
Second, remove many=True from:
show = ShowSerializer(read_only=True, many=True)
I am trying to get all products related to an orderitem but am having a problem doing the query.
I want to list all products in an orderitem. Hope i have provided everything needed.
from django.core.validators import RegexValidator
from django.db import models
from django.urls import reverse
from django.utils.text import slugify
from django.contrib.auth import get_user_model
class Order(models.Model):
ref_code = models.CharField(max_length=20, blank=True, null=True)
first_name = models.CharField(('first name'), max_length=30, blank=True)
last_name = models.CharField(('last name'), max_length=30, blank=True)
class Product(models.Model):
category = models.ForeignKey(Category,related_name='products',on_delete=models.CASCADE)
name = models.CharField(max_length=200, db_index=True, unique=True)
class OrderItem(models.Model):
order = models.ForeignKey(Order,related_name='items',on_delete=models.CASCADE)
product = models.ForeignKey(Product,related_name='order_items',on_delete=models.CASCADE)
price = models.DecimalField(max_digits=10, decimal_places=2)
quantity = models.PositiveIntegerField(default=1)
slug = models.SlugField(max_length=200, db_index=True)
Try this:
# Get list of product ids of a particular order
product_ids = OrderItem.objects.filter(order=order).values_list('product', flat=True)
# Get products from list of product ids
products = Product.objects.filter(id__in=product_ids)
Let me know if it helps :)
an idea to do thas
# For all_entries
all_entries = OrderItem.objects.all() #or all_entries = OrderItem.filter(order = order)
# one orderItem
for oi in orderItem:
products_of_one_oi = oi.product
for product in products_of_one_oi:
print(product)
I am trying to create a database schema for a simple Visitor Management System where I am creating two models named Visitor and Host by extending the inbuilt User model in Django. The model Appointment is for mapping the relation between the Visitor and Host with their meeting time slot. However, I am getting the 'demoapp.Appointment.host_email' refers to field 'email' which is not local to model 'demoapp.Host' error mentioned in the title when I run python manage.py makemigrations. Why am I getting this, how can I fix it and is there a better way to do it?
from django.db import models
from django.contrib.auth.models import User
from django.utils import timezone
from django.core.validators import RegexValidator
class Host(User):
class Meta:
verbose_name = "Host"
verbose_name_plural = "Hosts"
phone = models.CharField(verbose_name='Phone Number',max_length=10, validators=[RegexValidator(regex='[0-9]{10}')], unique=True, null=True)
class Visitor(User):
class Meta:
verbose_name = "Visitor"
verbose_name_plural = "Visitors"
phone = models.CharField(verbose_name='Phone Number',max_length=10, validators=[RegexValidator(regex='[0-9]{10}')], unique=True, null=True)
purpose = models.CharField(verbose_name='Purpose of meeting', max_length=150, null=True)
class Appointment(models.Model):
host_email = models.ForeignKey(Host, to_field='email', on_delete=models.CASCADE, verbose_name='Host Email')
visitor_email = models.ForeignKey(Visitor, to_field='email', on_delete=models.CASCADE, verbose_name='Visitor Email')
slot = models.DateField(verbose_name='Appointment Slot', default=timezone.now)
is_confirmed = models.BooleanField(verbose_name='Booking Confirmed', default=False)
Why are you specifying to_field in your foreign key? I think you may be misusing it. See the docs. You probably just want to leave that option off, and let Django use the primary key (id) of Host.
If you do mean to use it, you need an email attribute of your model Host. That is what the error is telling you. You'll also need to make this unique if you're going to use it as the field for your ForeignKey.
from django.db import models
from django.contrib.auth.models import User
from django.utils import timezone
from django.core.validators import RegexValidator
class Host(User):
class Meta:
verbose_name = "Host"
verbose_name_plural = "Hosts"
phone = models.CharField(verbose_name='Phone Number',max_length=10, validators=[RegexValidator(regex='[0-9]{10}')], unique=True, null=True)
email = models.EmailField(unique=True) # You're missing this
class Visitor(User):
class Meta:
verbose_name = "Visitor"
verbose_name_plural = "Visitors"
phone = models.CharField(verbose_name='Phone Number',max_length=10, validators=[RegexValidator(regex='[0-9]{10}')], unique=True, null=True)
purpose = models.CharField(verbose_name='Purpose of meeting', max_length=150, null=True)
class Appointment(models.Model):
host_email = models.ForeignKey(Host, to_field='email', on_delete=models.CASCADE, verbose_name='Host Email')
visitor_email = models.ForeignKey(Visitor, to_field='email', on_delete=models.CASCADE, verbose_name='Visitor Email')
slot = models.DateField(verbose_name='Appointment Slot', default=timezone.now)
is_confirmed = models.BooleanField(verbose_name='Booking Confirmed', default=False)
my apologies as I am new to Django and this seems like a "Django 101" type problem, but I just can't seem to get it to work. I have a Django model for "Services" which has a related model for "Keywords" via a one-to-many relationship. I'm simply trying to return the related keywords when I query the services, but when I run the view, I keep getting the error:
Invalid field name(s) given in select_related: 'keyword'. Choices are: (none)
My models are as follows:
from uuid import uuid4
from django.db import models
from django.utils.text import slugify
from blog.models import Tag, Category
class Service(models.Model):
id_service = models.UUIDField(primary_key=True, default=uuid4, editable=False)
created_ts = models.DateTimeField(auto_now_add=True)
updated_ts = models.DateTimeField(auto_now=True)
service_name = models.CharField(
db_index=True, max_length=50, blank=False, null=False
)
slug = models.CharField(max_length=50, unique=True)
font_awesome_icon = models.CharField(blank=True, null=True, max_length=30)
service_image = models.ImageField(
blank=True, null=True, upload_to="images/services", max_length=None
)
service_page_image = models.ImageField(
blank=True, null=True, upload_to="images/services", max_length=None
)
service_description = models.TextField(blank=False, null=False)
service_description_brief = models.CharField(
max_length=200, blank=False, null=False
)
rank = models.IntegerField()
def save(self, *args, **kwargs):
self.slug = slugify(self.service_name)
super(Service, self).save(*args, **kwargs)
def __str__(self):
return self.service_name
class ServiceKeyword(models.Model):
id_servicekeywords = models.UUIDField(
primary_key=True, default=uuid4, editable=False
)
created_ts = models.DateTimeField(auto_now_add=True)
updated_ts = models.DateTimeField(auto_now=True)
keyword = models.CharField(max_length=60, blank=False, null=False)
service = models.ForeignKey(Service, on_delete=models.CASCADE)
def __str__(self):
return self.keyword
And the view that is throwing the error is:
import random
import markdown2
import geoip2.database
import datetime
from django.views.generic.base import TemplateView
from django.views.generic.list import ListView
from django.core.paginator import Paginator
from django.http import Http404
from django.shortcuts import render
from django.urls import reverse
from services.models import Service, ServiceKeyword
class ServiceView(TemplateView):
template_name = "services/service.jinja"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
servicename = self.kwargs["servicename"]
service_list = Service.objects.select_related("keyword").order_by("rank")
context["service_list"] = service_list
context["faq_list"] = Post.objects.filter(categories__slug=servicename)
for faq in context["faq_list"]:
faq.content = markdown2.markdown(faq.content)
# Get service with that slug and take from list
service = service_list.filter(slug=servicename)[0]
context["keyword_list"] = service.keyword.all().order_by("?")[7]
context["service"] = service
)
return context
Any help from the pros would be greatly appreciated, as I've looked at the docs and spend an inordinate amount of time trying to fix. Thank you!
Defining a related_name on your field definition should solve your problem :
class ServiceKeyword(models.Model):
...
service = models.ForeignKey(Service, related_name='keyword', on_delete=models.CASCADE)
...
You can find the documentation for the related_name HERE
I am facing an error in one of my Django practice projects.
Following are my apps and respective models:
Project name: django03
app: home
home/model.py
from __future__ import unicode_literals
from django.db import models
from django.conf import settings
# Create your models here.
User = settings.AUTH_USER_MODEL
HOME_TYPE = (
('1','1'),
('2','2'),
('3','3'),
)
class Home(models.Model):
home_owner = models.ForeignKey(User,null=False, verbose_name='Owner')
hometype= models.CharField(max_length=100, null=False, default=1,
choices=HOME_TYPE, verbose_name='Home Type')
licenseid= models.CharField(max_length=200, null=False, unique=True,
verbose_name='License ID')
archive = models.BooleanField(default=False)
def __str__(self):
return self.licenseid
app: furniture
furniture/model.py
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.conf import settings
from django.db import models
# Create your models here.
User = settings.AUTH_USER_MODEL
FURNITURE_DATA_IMPORT_SOURCE= (
('0', '0'),
('1', '1'),
('2', '2'),
)
class Furniture(models.Model):
furniture_owner = models.ForeignKey(User, verbose_name='User')
furniture_imported_via = models.CharField(max_length=200, default="0", null=False, choices=FURNITURE_DATA_IMPORT_SOURCE, verbose_name='Source of import')
furniture_title = models.CharField(max_length=100, null=False, verbose_name='Furniture title')
furniture_description = models.TextField(max_length=250, verbose_name='Furniture description')
archive = models.BooleanField(default=False)
def __str__(self):
return self.furniture_title
app:mappings
mappings/model.py
from __future__ import unicode_literals
from django.db import models
from home.models import Home
from furniture.models import Furniture
class HomeFurnitureMapping(models.Model):
home = models.OneToOneField(
Home,
on_delete=models.CASCADE,
null=False,
unique=True,
verbose_name='Home'
)
furniture = models.OneToOneField(
Furniture,
on_delete=models.CASCADE,
null=False,
unique=True,
verbose_name='Furniture'
)
app: furnitureupdates
furnitureupdates/model.py
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models
from mappings.models import HomeFurnitureMapping
# Create your models here.
class FurnitureUpdate(models.Model):
mapping_id = models.OneToOneField(
HomeFurnitureMapping,
on_delete=models.CASCADE,
null=False,
unique=True,
verbose_name='Mapping ID'
)
update_status = num_pages = models.IntegerField(null=False, default=1)
update_date = models.DateField(auto_now_add=True, null=False, verbose_name='Update date')
update_time = models.TimeField(auto_now_add=True, null=False, verbose_name='Update time')
def __str__(self):
return self.mapping_id
When I try to migrate the FurnitureUpdate model, I get the following error:
ERRORS:
furnitureupdates.FurnitureUpdate.num_pages: (models.E006) The field 'num_pages' clashes with the field 'num_pages' from model 'furnitureupdates.furnitureupdate'.
I am not understanding from where the num_pages field is appearing. Please guide me, how to resolve this issue.
You need to update this;
update_status = num_pages = models.IntegerField(null=False, default=1)
to
update_status = models.IntegerField(null=False, default=1)
or;
num_pages = models.IntegerField(null=False, default=1)