Django Forcing BigAutoField even though Default is set to AutoField - django

so I upgraded from django 3.1 to 3.2 and on two of my models when I make migrations it keeps forcing me to change the auto id to BigAutoField even though I have (and had) DEFAULT_AUTO_FIELD = 'django.db.models.AutoField' in my settings file before I updated.
operations = [
migrations.AlterField(
model_name='device',
name='id',
field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
)
What is strange is that it is only affecting a couple models, but the rest are fine and they all use AutoField as well.
I am not against using BigAutoField but the migration fails because of foreignkey constraints.
I have deleted the migrations in question and also scrubbed them from the applied migrations table in the database. How can I stop Django from forcing this migration? I am at a loss right now.
Here is my Device Model. As you can see I have not specifically set the primary key, which I have not done on any other model either and those are fine.
from django.db import models
from company.models import Company
from django.db.models.signals import pre_save, post_save
from main.models import uuid_pre_save_generator
from django.conf import settings
from asgiref.sync import async_to_sync
from channels.layers import get_channel_layer
import json
from django.urls import reverse
from django.utils.html import escape
from django.core.validators import RegexValidator, FileExtensionValidator
class UploadedImage(models.Model):
uuid = models.CharField(max_length=7, blank=True, unique=True, verbose_name='Image ID')
image = models.ImageField(null=True, blank=True, upload_to="images/",
validators=[FileExtensionValidator(['jpg', 'png', 'jpeg'], 'Only .jpg files allowed')])
objects = models.Manager()
class Meta:
verbose_name = "Uploaded Image"
verbose_name_plural = "Uploaded Images"
def __str__(self):
return self.uuid
pre_save.connect(uuid_pre_save_generator, sender=UploadedImage)
def update_device_theme(sender, instance, *args, **kwargs):
related_devices = instance.devices.all()
if related_devices:
for d in related_devices:
d.save()
def alert_device_update(sender, instance, *args, **kwargs):
device = Device.objects.get(uuid=instance.uuid)
channel_layer = get_channel_layer()
group_name = 'connect_{}'.format(instance.uuid)
data = json.dumps({
'message': {
'type': 'device_update',
'text': '',
'data': {
'device': device.connect,
},
'sender': {
'type': 'server',
'uuid': '',
'first_name': '',
'last_name': '',
'company': '',
'initial': '',
'display_name': 'Server',
},
},
})
async_to_sync(channel_layer.group_send)(
group_name,
{
'type': 'chatroom.message',
'text': data
}
)
class DeviceDisplayTheme(models.Model):
uuid = models.CharField(max_length=7, blank=True, unique=True, verbose_name='Theme ID')
name = models.CharField(max_length=30, blank=False, null=False, verbose_name='Theme Name')
show_header = models.BooleanField(default=True, verbose_name='Show Header')
show_footer = models.BooleanField(default=True, verbose_name='Show Footer')
header_bg_color = models.CharField(max_length=30, blank=False, null=False,
verbose_name='Header Background Color',
default='rgba(255,255,255,.1)',
validators=[
RegexValidator(
regex=r"^^rgba[(](?:\s*0*(?:\d\d?(?:\.\d+)?(?:\s*%)?|"
r"\.\d+\s*%|100(?:\.0*)?\s*%|(?:1\d\d|2[0-4]\d|"
r"25[0-5])(?:\.\d+)?)\s*,){3}\s*0*(?:\.\d+|1(?:\.0*)?)\s*[)]$",
message='The header background color you have chosen is not formatted'
' correctly',
),
])
badge_bg_color = models.CharField(max_length=30, blank=False, null=False,
verbose_name='Device ID Badge Background Color',
default='rgba(255,255,255,.2)',
validators=[
RegexValidator(
regex=r"^^rgba[(](?:\s*0*(?:\d\d?(?:\.\d+)?(?:\s*%)?|"
r"\.\d+\s*%|100(?:\.0*)?\s*%|(?:1\d\d|2[0-4]\d|"
r"25[0-5])(?:\.\d+)?)\s*,){3}\s*0*(?:\.\d+|1(?:\.0*)?)\s*[)]$",
message='The badge background color you have chosen is not formatted'
' correctly',
),
])
bg_color = models.CharField(max_length=30, blank=False, null=False,
verbose_name='Background Color',
default='rgba(35,35,35,1)',
validators=[
RegexValidator(
regex=r"^^rgba[(](?:\s*0*(?:\d\d?(?:\.\d+)?(?:\s*%)?|"
r"\.\d+\s*%|100(?:\.0*)?\s*%|(?:1\d\d|2[0-4]\d|"
r"25[0-5])(?:\.\d+)?)\s*,){3}\s*0*(?:\.\d+|1(?:\.0*)?)\s*[)]$",
message='The background color you have chosen is not formatted correctly',
),
])
font_color = models.CharField(max_length=30, blank=False, null=False,
verbose_name='Font Color',
default='rgba(255,255,255,1)',
validators=[
RegexValidator(
regex=r"^^rgba[(](?:\s*0*(?:\d\d?(?:\.\d+)?(?:\s*%)?|"
r"\.\d+\s*%|100(?:\.0*)?\s*%|(?:1\d\d|2[0-4]\d|"
r"25[0-5])(?:\.\d+)?)\s*,){3}\s*0*(?:\.\d+|1(?:\.0*)?)\s*[)]$",
message='The font color you have chosen is not formatted correctly',
),
])
idle_text = models.CharField(max_length=50, blank=True, null=True,
verbose_name="Idle Text",
default='Press Help Button In Case of Emergency')
help_requested_text = models.CharField(max_length=50, blank=True, null=True,
verbose_name="Help Requested Text",
default='Emergency Help Requested')
active_text = models.CharField(max_length=50, blank=True, null=True,
verbose_name="Active Call Text",
default='Emergency Call Accepted')
response_prompt_text = models.CharField(max_length=50, blank=True, null=True,
verbose_name="Response Prompt Text",
default='Press Yes/No Buttons to Respond')
company = models.ForeignKey(Company, related_name='themes', verbose_name='Company',
blank=True, null=True, on_delete=models.CASCADE)
date_updated = models.DateTimeField(auto_now=True)
source_date_updated = models.DateTimeField(blank=True, null=True)
source_uuid = models.CharField(max_length=7, blank=True, null=True, verbose_name='Source ID')
objects = models.Manager()
class Meta:
verbose_name = "Device Display Theme"
verbose_name_plural = "Device Display Themes"
def __str__(self):
return self.name
#property
def settings(self):
idle_text = '' if not self.idle_text else self.idle_text
help_requested_text = '' if not self.help_requested_text else self.help_requested_text
active_text = '' if not self.active_text else self.active_text
response_prompt_text = '' if not self.response_prompt_text else self.response_prompt_text
return {
'pk': self.pk,
'name': escape(self.name),
'show_header': self.show_header,
'show_footer': self.show_footer,
'header_bg_color': self.header_bg_color,
'bg_color': self.bg_color,
'badge_bg_color': self.badge_bg_color,
'font_color': self.font_color,
'idle_text': escape(idle_text),
'help_requested_text': escape(help_requested_text),
'active_text': escape(active_text),
'response_prompt_text': escape(response_prompt_text),
}
#property
def settings_json(self):
return json.dumps(self.settings)
pre_save.connect(uuid_pre_save_generator, sender=DeviceDisplayTheme)
post_save.connect(update_device_theme, sender=DeviceDisplayTheme)
class Device(models.Model):
UUID_CREATED = 0
PROGRAMMED = 1
ASSIGNED = 2
lifecycle_stages = [
(UUID_CREATED, 'Unique ID Created'),
(PROGRAMMED, 'Memory Card Programmed'),
(ASSIGNED, 'Owner Assigned'),
]
statuses = [
('idle', 'Idle'),
('requested', 'Incoming Call Requested'),
('active', 'Live Call'),
]
uuid = models.CharField(max_length=6, blank=True, unique=True, verbose_name='Device ID')
# Call Status [ Idle, Requested, Active ]
state = models.CharField(max_length=10, choices=statuses, blank=False, default='idle', verbose_name="Call Status")
active = models.BooleanField(default=False, verbose_name='Active')
self_monitored = models.BooleanField(default=False, verbose_name='Self Monitored')
# Display Theme
theme = models.ForeignKey(DeviceDisplayTheme, related_name='devices', verbose_name='Display Theme',
blank=False, null=False, default=1, on_delete=models.SET_DEFAULT)
# Programming & Assignment
initialized = models.BooleanField(default=False, verbose_name='Initialized')
lifecycle = models.IntegerField(choices=lifecycle_stages, default=0, verbose_name="Lifecycle Stage")
software_version = models.CharField(max_length=12, blank=True, null=True, verbose_name='Software Version')
model_number = models.CharField(max_length=12, blank=True, null=True, verbose_name='Model Number')
activation_code = models.CharField(max_length=5, blank=True, null=True, verbose_name='Activation Code')
# Relationships
owner = models.ForeignKey(Company, related_name='devices', verbose_name='Device Owner',
blank=True, null=True, on_delete=models.SET_NULL)
callcenter = models.ForeignKey(Company, related_name='monitored_devices', verbose_name='Call Center',
on_delete=models.CASCADE, blank=True, null=True)
# Location & Address Details
location = models.CharField(max_length=255, blank=True, verbose_name='Device Identifier')
address = models.CharField(max_length=255, verbose_name="Street Address", blank=True)
address2 = models.CharField(max_length=255, verbose_name="Apartment, Unit, Suite, or Floor", blank=True)
address_locality = models.CharField(max_length=255, verbose_name="City/Town", blank=True)
address_state = models.CharField(max_length=255, verbose_name="State", blank=True)
address_postcode = models.CharField(max_length=55, verbose_name="Zip Code", blank=True)
address_country = models.CharField(max_length=55, verbose_name="Country", blank=True)
# Call-in Phone Number
phone_number = models.CharField(max_length=14, blank=True, null=True, verbose_name="Call-in Phone Number",
validators=[
RegexValidator(
regex=r"^\(\d{3}\)\s\d{3}-\d{4}$",
message='Phone number format is not valid, try (000) 000-0000',
),
])
# Timestamps
date_created = models.DateTimeField(auto_now_add=True)
date_updated = models.DateTimeField(auto_now=True)
date_last_online = models.DateTimeField(blank=True, null=True)
objects = models.Manager()
class Meta:
verbose_name = "Device"
verbose_name_plural = "Devices"
ordering = ['uuid']
def __str__(self):
return self.uuid
def set_idle_state(self):
self.state = 'idle'
def set_requested_state(self):
self.state = 'requested'
def set_active_state(self):
self.state = 'active'
#property
def full_address(self):
def check_address_parts(value):
if value == '' or value == ',':
return False
else:
return True
address_parts = [
"%s," % self.address,
"%s," % self.address2,
"%s" % self.address_locality,
"%s," % self.address_state,
"%s" % self.address_postcode,
]
return ' '.join(filter(check_address_parts, address_parts))
#property
def location_and_full_address(self):
if self.location:
if self.full_address:
return '{} - {}'.format(self.full_address, self.location)
return self.location
return self.full_address
#property
def entry(self):
address = '<div class="fs-6">{}</div>'.format(escape(self.full_address)) if self.full_address else ''
location = '<div class="fs-6">{}</div>'.format(escape(self.location)) if self.location else ''
return ' '.join((address, location))
#property
def connect(self):
owner = '' if not self.owner else self.owner.connect
callcenter = '' if not self.callcenter else self.callcenter.connect
return {
'type': 'device',
'pk': self.pk,
'uuid': self.uuid,
'state': self.state,
'first_name': '',
'last_name': '',
'owner': owner,
'callcenter': callcenter,
'initial': 'D',
'display_name': 'Device {}'.format(self.uuid),
'location': escape(self.location),
'address': escape(self.full_address),
'connect_version': settings.CONNECT_VERSION,
'url_live_call': reverse('device_live_call', args=[self.uuid]),
'theme': self.theme.settings,
}
#property
def connect_json(self):
return json.dumps(self.connect)
#property
def connect_version(self):
return settings.CONNECT_VERSION
pre_save.connect(uuid_pre_save_generator, sender=Device)
post_save.connect(alert_device_update, sender=Device)
class DeviceId(models.Model):
STAGED = 0
REQUESTED = 1
CAPTURED = 2
EXPIRED = 3
device_uuid_status = [
(STAGED, 'Staged'),
(REQUESTED, 'Requested'),
(CAPTURED, 'Captured'),
(EXPIRED, 'Expired'),
]
uuid = models.CharField(max_length=7, blank=True, unique=True, verbose_name='Device ID')
status = models.IntegerField(choices=device_uuid_status, default=0, verbose_name="ID Status")
programmer = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='programmer', null=True,
on_delete=models.PROTECT, verbose_name='Programmer')
# Timestamps
date_created = models.DateTimeField(auto_now_add=True)
date_requested = models.DateTimeField(blank=True, null=True)
date_captured = models.DateTimeField(blank=True, null=True)
date_expired = models.DateTimeField(blank=True, null=True)
objects = models.Manager()
class Meta:
verbose_name = "Device Id"
verbose_name_plural = "Device Ids"
ordering = ['date_created']
pre_save.connect(uuid_pre_save_generator, sender=DeviceId)

Well, I figured it out. For some reason the BigAutoField was set in the apps.py file in the app
from django.apps import AppConfig
class DeviceConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'device'

Related

association user with forms

I'm making something like this: admin creates form manually, and user is automatically created with this form.
But I need to add association that form to a new automatically created user, that's where I'm stuck. How can I make user auto registration to associate that form
I need this because I want to then to show 'filtered, created' form by user.
Views.py
def create_driver_view(request):
if request.method == "POST":
add_driver = DriverForm(request.POST)
add_driver_files = request.FILES.getlist("file")
if add_driver.is_valid():
email = request.POST['email']
usern = 'test'
passw = 'test'
user = User.objects.create_user(email = email, username = usern, password = passw)
user.save()
f = add_driver.save(commit=False)
f.user = request.user
f.save()
for i in add_driver_files:
DriversFiles.objects.create(driver_files=f, file=i)
return redirect('drivers:list_driver')
else:
print(add_driver.errors)
else:
add_driver = DriverForm()
add_driver_files = DriverFormUpload()
return render(request, "drivers/add.html", {"add_driver": add_driver, "add_driver_files": add_driver_files})
Forms.py
class DriverForm(forms.ModelForm):
class Meta:
model = Drivers
fields = [
'full_name',
'phone_number',
'email',
'address',
'country',
'state',
'city',
'zip',
'birth_date',
'license_no',
'license_exp_date',
'last_medical',
'next_medical',
'last_drug_test',
'next_drug_test',
'status',
]
class DriverFormUpload(forms.ModelForm):
class Meta:
model = DriversFiles
fields = [
'file',
]
widget = {
'file': forms.ClearableFileInput(attrs={'multiple': True}),
}
Models.py
STATUS = ((0, 'Inactive'), (1, 'Active'))
class Drivers(models.Model):
full_name = models.CharField(max_length=50, default=None)
phone_number = models.CharField(max_length=50, default=None)
email = models.EmailField(unique=True,max_length=255, default=None)
address = models.CharField(max_length=70, default=None)
country = models.CharField(max_length=50, default=None)
state = models.CharField(max_length=50, default=None)
city = models.CharField(max_length=50, default=None)
zip = models.CharField(max_length=50, default=None)
birth_date = models.DateField(default=None)
license_no = models.IntegerField(default=None)
license_exp_date = models.DateField(default=None)
last_medical = models.DateField(default='', blank=True, null=True)
next_medical = models.DateField(default='', blank=True, null=True)
last_drug_test = models.DateField(default='', blank=True, null=True)
next_drug_test = models.DateField(default='', blank=True, null=True)
date_created = models.DateTimeField(auto_now_add=True)
status = models.IntegerField(choices=STATUS, default=1)
class DriversFiles(models.Model):
file = models.FileField(upload_to="media/", blank=True, null=True)
driver_files = models.ForeignKey('Drivers', on_delete=models.CASCADE, default=None, null=True)

Django inlineformset: PK missing in subform -> form_set.is_valid() = False

I have followed this tutorial to implement inlneformset.
CreateView works (data is registered in database) but UpdateView doesn't.
UpdateView is correctly displayed with correct data.
But it seems like subform (application inlineformset) is never valid and I don't understand why?
forms.py:
NAME = Thesaurus.options_list(2,'fr')
ACCESS = Thesaurus.options_list(3,'fr')
ApplicationFormset = inlineformset_factory(
Utilisateur, Application,
fields=('app_app_nom','app_dro'),
widgets={
'app_app_nom': forms.Select(choices=NAME),
'app_dro': forms.Select(choices=ACCESS)
},
extra=3,
can_delete=True,
)
models.py:
class Projet(SafeDeleteModel):
_safedelete_policy = SOFT_DELETE_CASCADE
pro_ide = models.AutoField(primary_key = True)
pro_nom = models.IntegerField("Nom du projet", null=True, blank=True)
pro_log = models.CharField("Log utiisateur", max_length=20, null=True, blank=True)
pro_dat = models.DateTimeField("Date log",auto_now_add=True)
pro_act = models.IntegerField("Projet en cours ?", null=True, blank=True)
log = HistoricalRecords()
class Meta:
db_table = 'tbl_pro'
verbose_name_plural = 'Projets'
ordering = ['pro_ide']
permissions = [
('can_add_project','Can add project'),
]
class Utilisateur(SafeDeleteModel):
_safedelete_policy = SOFT_DELETE_CASCADE
uti_ide = models.AutoField(primary_key = True)
pro_ide = models.ForeignKey(Projet, on_delete = models.CASCADE) # related project
uti_nom = models.CharField("Nom", max_length=20, null=True, blank=True)
uti_pre = models.CharField("Prénom", max_length=20, null=True, blank=True)
uti_mai = models.CharField("Email", max_length=40, null=True, blank=True)
uti_sit = models.CharField("Equipe", max_length=20, null=True, blank=True)
uti_pro = models.CharField("Fonction/profil", max_length=200, null=True, blank=True)
uti_dem_dat = models.DateTimeField("Date demande",auto_now_add=True, null=True, blank=True)
uti_val = models.IntegerField("Demande validée ?", null=True, blank=True)
uti_val_dat = models.DateTimeField("Date validation",auto_now_add=True, null=True, blank=True)
uti_log = models.CharField("Log utilisateur", max_length=20, null=True, blank=True)
uti_dat = models.DateTimeField("Date log",auto_now_add=True, null=True, blank=True)
log = HistoricalRecords()
#classmethod
def options_list(cls,pro_ide):
projet = Projet.objects.get(pro_ide=pro_ide)
utilisateurs = Utilisateur.objects.filter(pro_ide=projet.pro_ide)
the_opts_list = [(utilisateur.uti_ide, utilisateur.uti_nom+', '+utilisateur.uti_pre) for utilisateur in utilisateurs]
the_opts_list.insert(0, (None, ''))
return the_opts_list
class Meta:
db_table = 'tbl_uti'
verbose_name_plural = 'Utilisateurs'
ordering = ['uti_ide']
class Application(SafeDeleteModel):
_safedelete_policy = SOFT_DELETE_CASCADE
app_ide = models.AutoField(primary_key = True)
uti_ide = models.ForeignKey(Utilisateur, on_delete = models.CASCADE) # related utilisateur
app_app_nom = models.IntegerField("Nom application", null=True, blank=True)
app_dro = models.IntegerField("Droit sur application", null=True, blank=True)
app_sta = models.IntegerField("Statut (création/Modification/Suppression", null=True, blank=True)
app_log = models.CharField("Log utilisateur", max_length=20, null=True, blank=True)
app_dat = models.DateTimeField("Date log",auto_now_add=True, null=True, blank=True)
log = HistoricalRecords()
class Meta:
db_table = 'tbl_app'
verbose_name_plural = 'Applications'
ordering = ['app_ide']
class Administration(SafeDeleteModel):
_safedelete_policy = SOFT_DELETE_CASCADE
adm_ide = models.AutoField(primary_key = True)
app_ide = models.ForeignKey(Application, on_delete = models.CASCADE) # related application
adm_nom = models.CharField("Nom d'utilisateur dans l'application", max_length=20, null=True, blank=True)
adm_dem = models.IntegerField("Demande traitée ?", null=True, blank=True)
adm_dem_dat = models.DateTimeField("Date traitement de la demande",auto_now_add=True)
adm_log = models.CharField("Log utilisateur", max_length=20, null=True, blank=True)
adm_dat = models.DateTimeField("Date log",auto_now_add=True)
log = HistoricalRecords()
class Meta:
db_table = 'tbl_adm'
verbose_name_plural = 'Adminitrations'
ordering = ['adm_ide']
permissions = [
('can_manage_project','Can manage project'),
]
UpdateView:
class UtilisateurUpdateView(UpdateView):
model = Utilisateur
fields = ['uti_nom','uti_pre','uti_mai','uti_sit','uti_pro']
def get_context_data(self, **kwargs):
data = super().get_context_data(**kwargs)
if self.request.POST:
data["utilisateur"] = self.request.user.username
data["application"] = ApplicationFormset(self.request.POST, instance=self.object)
else:
data["application"] = ApplicationFormset(instance=self.object)
return data
def form_valid(self, form):
context = self.get_context_data()
application = context["application"]
self.object = form.save()
self.object.save()
if application.is_valid(): # ***** NEVER VALID *****
application.instance = self.object
print('application.instance',application.instance)
application.app_app_nom = application.instance.cleaned_data['app_app_nom']
application.app_dro = application.instance.cleaned_data['app_dro']
application.app_log = context["utilisateur"]
application.uti_ide = 1
application.save()
return super().form_valid(form)
def get_success_url(self):
return reverse("project:index")
I have resolve my problem: I forget to insert form_set id in my html template (app_ide in my case)

How to filter a model in django?

So i have a model called Partner. A business is a partner. I have a foreignkey field who takes self as a parameter to create choices. What i want to do is to go through all the created partners and filter out ones that are parent companies. I was thinking of having a boolean that says is_parent. How do i go about this can i search for the boolean in the database and create a choicefield or something with it so i can get a list of parent companies?
What i am trying to do is filter the parents and either make the filtered objects into a choicefiled or make a second model with it so i can offer the choice of selecting the parent.
I have tried to filter through my result but that did not work as expected.
from django.db import models
from django.urls import reverse
from model_utils import Choices
from model_utils.fields import StatusField
from model_utils.models import StatusModel, TimeStampedModel
from phone_field import PhoneField
from addresses.models import Address
from
common.utils import COUNTRIES
class Industry(models.Model):
""" Business Industry model """
name = models.CharField(max_length=100)
class Meta:
verbose_name = 'Industry'
verbose_name_plural = 'Industries'
ordering = ('name',)
def __str__(self):
return '%s' % self.name
class PartnerType(models.Model):
name = models.CharField(blank=False,
help_text="Name of the role or function", max_length=64,
verbose_name="Partner Type", )
class Meta:
verbose_name = 'partner type'
verbose_name_plural = 'partner types'
# TO STRING METHOD
def __str__(self):
return '%s' % self.name
class Partner(TimeStampedModel, StatusModel):
INVOICE_METHOD_CHOICE = (
("PAPER", "Paper"),
('EMAIL', 'Email'),
)
LEGAL_STRUCTURE_CHOICES = (
('CORPORATION', 'Corporation'),
('LLC', 'LLC'),
('SOLE PROPRIETOR', 'Sole Proprietor'),
('PARTNERSHIP', 'Partnership'),
)
PARTNER_OFFICE_CHOICES = (
('HEADQUARTERS', 'Headquarters'),
('DIVISION', 'Division Office'),
('SITE', 'Site'),
('DC', 'Distribution Center'),
)
ADDRESS_TYPES = (
('Billing', 'Billing'),
('Shipping', 'Shipping'),
('Physical', 'Physical'),
)
STATUS = Choices('Active', 'Inactive', 'Credit Hold',)
name = models.CharField(blank=True, max_length=100, verbose_name='Account Name', )
office_level = models.CharField(
choices=PARTNER_OFFICE_CHOICES, max_length=50, blank=True,)
trade_name = models.CharField(blank=True, max_length=100, verbose_name='Trade Name', )
logo = models.ImageField(default='default.jpg', upload_to='partners/logos')
industry = models.ForeignKey(
Industry,
blank=True,
help_text="Industry",
null=True,
on_delete=models.SET_NULL,
related_name="partners_industry", )
csp_rank = models.IntegerField(blank=True,null=True )
partner_types = models.ManyToManyField(PartnerType)
account_number = models.IntegerField(blank=True, editable=True,default=0)
vendor_number = models.CharField(blank=True, help_text="TEAZZERS account number with the partner", max_length=20,)
phone = PhoneField(blank=True, null=True, )
fax = PhoneField(blank=True, null=True, )
email = models.EmailField('main email address', blank=True)
ap_email = models.EmailField('AP email address', blank=True)
ar_email = models.EmailField('AR email address', blank=True)
website = models.URLField('Website', blank=True)
description = models.TextField(blank=True)
total_units = models.PositiveIntegerField(blank=True, null=True, verbose_name='Total units',
help_text='How many locations does this organization have?')
parent = models.ForeignKey(
'self',
blank=True,
help_text="Parent Company name (if necessary)",
null=True,
on_delete=models.CASCADE,
max_length=200
)
# if total_units > 0:
# status = 'Parent'
#
# if status == "Parent":
# parent = models.ForeignKey(
# 'self',
# blank=True,
# help_text="Parent Company name (if necessary)",
# null=True,
# on_delete=models.CASCADE,
# related_name="partners_partner", )
w9 = models.BooleanField(default=False, verbose_name='IRS Form W-9',
help_text='Have we received a completed IRS Form W-9?',)
legal_structure = models.CharField(
choices=LEGAL_STRUCTURE_CHOICES, max_length=50, blank=True,
help_text='How is the business structured?',)
ein = models.CharField(max_length=9, blank=True, default='', verbose_name='Federal Employer Identification Number')
duns = models.CharField(max_length=13, blank=True, default='', verbose_name='Dun & Bradstreet (DUNS) Number')
gln = models.CharField(max_length=13, blank=True, default='', verbose_name='GLN (GS1 Global Location Number)')
insurance = models.BooleanField(default=False, verbose_name='Insurance',
help_text='Have we received liabilty insurance paperwork?',)
insurance_end_date = models.DateField(blank=True, null=True, verbose_name='Insurance End Date',
help_text="When does insurance on file end? "
"Please use the following format: <em>YYYY-MM-DD</em>.")
insurance_files = models.FileField(upload_to='partners/insurance', blank=True,
verbose_name='Current Insurance Paperwork')
sales_tax = models.BooleanField(default=False, verbose_name='Sales Tax Paperwork',
help_text='Have we received Uniform Sales & Use Tax Certificate?',)
sales_tax_files = models.FileField(upload_to='partners/sales_tax', blank=True,
verbose_name='Current Insurance Paperwork')
invoice_method = models.CharField(
choices=INVOICE_METHOD_CHOICE, max_length=64, default='paper')
start_date = models.DateField(blank=True, null=True, verbose_name='Active Since',
help_text="When we begin doing business? Please use the"
" following format: <em>YYYY-
MM-DD</em>.")
address_type = models.CharField(
max_length=20, choices=ADDRESS_TYPES,blank=True)
street1 = models.CharField(
'Street Line 1', max_length=100, blank=True)
street2 = models.CharField(
'Street Line 2', max_length=100, blank=True)
city = models.CharField('City', max_length=100, blank=True)
state = models.CharField('State', max_length=100, blank=True)
postcode = models.CharField('Post/Zip-code', max_length=32, blank=True)
country = models.CharField(
max_length=3, choices=COUNTRIES, blank=True)
def __str__(self):
# return self.city if self.city else ""
return '%s' % self.full_address
#property
def full_address(self):
return ' %s %s %s %s %s' % (self.street1, self.street2, self.city,
self.state, self.postcode)
def get_complete_address(self):
address = ""
if self.street1:
if address:
address += ", " + self.street1
else:
address += self.street1
if self.street2:
if address:
address += ", " + self.street2
else:
address += self.street2
if self.city:
if address:
address += ", " + self.city
else:
address += self.city
if self.state:
if address:
address += ", " + self.state
else:
address += self.state
if self.postcode:
if address:
address += ", " + self.postcode
else:
address += self.postcode
if self.country:
if address:
address += ", " + self.get_country_display()
else:
address += self.get_country_display()
return address
primary_address = models.ForeignKey(
Address,
blank=True,
help_text="Primary Address",
null=True,
on_delete=models.SET_NULL,
related_name="partners_industry")
# MANAGERS
parent_list = list()
# META CLASS
class Meta:
verbose_name = 'partner'
verbose_name_plural = 'partners'
# TO STRING METHOD
def __str__(self):
return '%s' % self.name
#property
def full_name(self):
return '%s %s' % (self.name, self.site_id)
# SAVE METHOD
def save(self, *args, **kwargs):
super(Partner, self).save(*args, **kwargs)
#self.account_number = self.pk + 1000
# ABSOLUTE URL METHOD
def get_absolute_url(self):
return reverse('partners:detail', kwargs={'pk': self.pk})
def get_delete_url(self):
return reverse('partners:delete', kwargs={'pk': self.pk})
'''
this query will get you all the parent companies in all levels
assume that we have a structure like that
1 is parent of 3 and 4
2 is a parent of 6 and 5
3 is a parent of 9 and 10
4 is a parent of 11 and 12
6 has no sons
5 is a parent of 7 and 8
13 has no parent # parent = None
so (1, 2, 3, 4, 5) is a parent as every one has at least one son
parents = ModelName.objects.exclude(parent=None).values_list('parent', flat=True).annotate(count = Count('parent')).order_by('parent')
this return for you a list of ids for all parents
you can get queryset of parents as below
parents_queryset = ModelName.objects.filter(id__in=list(parents))
note : parent means it already have at least one son
if you need to get with them the node which already doesn't have parent # parent is None
and assume that it have no parent so it is a parent
new_parents_queryset = parents_queryset | ModelName.objects.filter(parent=None)
# this queryset is all the parents that have at least one son or the parents that have no parent
here (1, 2, 3, 4, 5, 13) is the parents as 13 have no parent
Assuming you have some other model (not shown in your models.py above) for which you want to only have parent companies be available for selection, first define a callable:
parent_companies():
return Partner.objects.exclude(parent=None).values_list('id', 'name')
Then use the callable for choices=:
class SomeModel(models.Model):
some_company = models.ForeignKeyField(Partner, choices=parent_companies())

Django Custom Tables Creation

I have a project where i have to create a command table for the customers to command on the site. What I am trying to achieve is to give the possibility of selecting multiple products to the customer. The foreign key is ok for one product, but when we have to select multiple ones, is not ok. Even when clicking the "+"add button, you are not allowed to add more, but django makes you add a new product in the DB :D.
How can i achieve my target of adding multiple products to the cart?
Thank you in advance!
My models;
from django.db import models
from django.conf import settings
from django.core.exceptions import ValidationError
from django.utils.translation import gettext_lazy as _
from datetime import datetime, timedelta, time
today = datetime.now().date()
class ClientManager(models.Manager):
def active(self, *args, **kwargs):
return super(ClientManager, self).filter(timestamp__lte=datetime.now())
class Client(models.Model):
TYPE_CLIENT = (
('PF', 'Persoana Fizica'), ('PJ', 'Persoana Juridica'),)
MODEL_CLIENT = (
('O', 'On-line'), ('S', 'Showroom'), ('D', 'Distribuitor'))
user = models.ForeignKey(settings.AUTH_USER_MODEL,blank=True, null=True, default=1, on_delete=True)
model_client = models.CharField(max_length=3, blank=True, default="PF", null=True,
choices=MODEL_CLIENT, help_text='Selecteaza de unde vine clientul')
tip_client = models.CharField(max_length=3, blank=True, default="PF", null=True,
choices=TYPE_CLIENT, help_text='Selecteaza tipul de client')
nume_client = models.CharField(max_length=30, blank=True, default="", null=True,
help_text='Insereaza Numele si Prenumele Clientului')
adresa_client = models.CharField(max_length=50, blank=True, default="", null=True,help_text='Insereaza Adresa Clientului')
cnp_client = models.CharField(
max_length=12, blank=True, default="", null=True, help_text='Insereaza CNP-ul Clientului')
serie_numar_client = models.CharField(max_length=20, blank=True, default="", null=True,help_text='Insereaza Seria si Numarul Clientului')
email = models.EmailField(blank=True, null=True)
nume_firma = models.CharField(max_length=30, blank=True, default="",null=True, help_text='Insereaza Numele Firmei')
cui_firma=models.CharField(max_length=10, blank=True, default="",null=True, help_text='Insereaza CUI-ul Firmei')
adresa_firma = models.CharField(
max_length=70, blank=True, default="", null=True, help_text='Insereaza Adresa Firmei')
updated = models.DateTimeField(auto_now=True, auto_now_add=False, blank=True, null=True)
timestamp = models.DateTimeField(auto_now=False, auto_now_add=True, blank=True, null=True)
objects = ClientManager()
def __str__(self):
return str(self.nume_client) + " | " + str(self.adresa_client) + " | " + str(self.adresa_firma) + " | " + str(self.nume_firma) + " | " + str(self.timestamp)
class Meta:
verbose_name_plural = "client"
ordering = ["-timestamp"]
class ProdusManager(models.Manager):
def active(self, *args, **kwargs):
return super(ProdusManager, self).filter(timestamp__lte=datetime.now())
class Produs(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL,
blank=True, null=True, default=1, on_delete=True)
nume_produs = models.CharField(max_length=30, blank=True, null=True,
help_text='Adauga Nume Produs')
pret_produs = models.IntegerField(blank=True, null=True,help_text='Introdu Pretul Produsului')
timestamp = models.DateTimeField(
auto_now=False, auto_now_add=True, blank=True, null=True)
objects = ProdusManager()
def __str__(self):
return str(self.nume_produs) + " | " + str(self.pret_produs)
class Meta:
verbose_name_plural = "produs"
ordering = ["-timestamp"]
class ComandaManager(models.Manager):
def active(self, *args, **kwargs):
return super(ComandaManager, self).filter(timestamp__lte=datetime.now())
class Comanda(models.Model):
STATUS_PRODUS = (
('S', 'Stoc'), ('SD', 'Stoc Distribuitor'), ('L', 'Livrat'))
user = models.ForeignKey(settings.AUTH_USER_MODEL,
blank=True, null=True, default=1, on_delete=True)
nume_client_comanda = models.ForeignKey(
Client, related_name='nume_client_comanda', on_delete=models.CASCADE)
nume_firma_comanda = models.ForeignKey(
Client, related_name='nume_firma_comanda', on_delete=models.CASCADE)
produsul_comandat = models.ForeignKey(
Produs, related_name='produsul_comandat', on_delete=models.CASCADE)
pretul_comandat = models.ForeignKey(
Produs, related_name='pretul_comandat', on_delete=models.CASCADE)
cantitate = models.IntegerField (blank = True, null = True, help_text = 'Introdu Cantitatea Produsului')
status_produs = models.CharField(max_length=3, blank=True, default="PF", null=True,
choices=STATUS_PRODUS, help_text='Selecteaza de unde vine clientul')
pret_comanda = models.IntegerField(
blank=True, null=True, help_text='Introdu Pretul Comenzii')
timestamp = models.DateTimeField(
auto_now=False, auto_now_add=True, blank=True, null=True)
objects = ComandaManager()
def __str__(self):
return str(self.nume_client_comanda) + " | " + str(self.pret_comanda)
# def __str__(self):
# return "%s %s" % (self.first_name, self.last_name)
class Meta:
verbose_name_plural = "comanda"
ordering = ["-timestamp"]
You need a Many to Many relationship, not ForeignKey (Many-to-One)
This way multiple Clients can each have multiple Products.
Right now, two different Clients cannot have the same Product because you used ForeignKey.

I need to display summary report in Django admin site. How do I count number of users where gender status is 0 or 1

I am overriding change_list.html and here is what I have in my admin.py file.
class MyHelperGenderAdmin(admin.ModelAdmin):
change_list_template = 'admin/helper_chart_change_list.html'
date_hierarchy = 'created_at'
list_filter = ('gender', 'created_at')
def changelist_view(self, request, extra_context=None):
response = super().changelist_view(request, extra_context=extra_context, )
try:
qs = response.context_data['cl'].queryset
except (AttributeError, KeyError):
return response
metrics = {
'male': Count('gender', gender=1),
'female': Count('gender', gender=0),
'total_helpers': Count('id')
}
response.context_data['helper'] = list(
qs.values('gender').annotate(**metrics).order_by('-male')
)
return response
def has_add_permission(self, request):
return False
admin.site.register(MyHelperChart, MyHelperGenderAdmin)
In my metrics dictionary, i need a way to count where gender is either 0 or 1. Currently, The count method count everything regards of the gender status.
Here is my model:
class Helper(auth.models.User):
MALE = 1
FEMALE = 0
GENDER_CHOICES = (
(MALE, 'Male'),
(FEMALE, 'Female')
)
phone_regex = RegexValidator(regex=r'^\+?1?\d{9,15}$',
message=
"Phone number must be entered in the format: '+999999999'. Up to 15 digits allowed."
)
phone_number = models.CharField(validators=[phone_regex], max_length=15, blank=True, unique=True, null=True)
gender = models.IntegerField(choices=GENDER_CHOICES, default=MALE, null=True)
birthdate = models.DateField(blank=True, null=True)
facebook_id = models.CharField(max_length=200, blank=True, null=True)
google_id = models.CharField(max_length=200, blank=True, null=True)
lng = models.FloatField(blank=True, null=True)
lat = models.FloatField(blank=True, null=True)
country = models.ForeignKey(Country, blank=True, null=True)
image = models.ImageField(
upload_to=upload_location,
null=True, blank=True,
width_field="width_field",
height_field="height_field")
height_field = models.IntegerField(default=0)
width_field = models.IntegerField(default=0)
updated_at = models.DateTimeField(auto_now=True)
created_at = models.DateTimeField(auto_now=False, auto_now_add=True)
class Meta:
verbose_name_plural = "Helpers"
def __str__(self):
return self.first_name
class MyHelperChart(Helper):
class Meta:
proxy = True
verbose_name = 'Helper Gender Summmary'
verbose_name_plural = 'Helpers Gender Summaries'
I have created a proxy model which I will be using in my Django admin in order to display summary of data and a chart.
All you need to do is add a case to both the male and female metrics. Here's an example, and then you can do the same for female = 0:
from django.db.models import Case, When, IntegerField
class MyHelperGenderAdmin(admin.ModelAdmin):
...
metrics = {
...
'male': Count(Case(
When(gender = 1, then = 1),
output_field = IntegerField())),
...
}