models clash with (META) inheritance - python

in a django project i' ve multiple apps, and the common contains the following models:
class CLDate(models.Model):
class Meta:
abstract = True
active = models.BooleanField(default=True)
last_modified = models.DateTimeField(auto_now=True)
created = models.DateTimeField(auto_now_add=True)
class Switch(CLDate):
name = models.CharField(max_length=64)
code = models.CharField(max_length=64, blank=True, null=True)
description = models.TextField(blank=True, null=True)
sorted = models.IntegerField(default=0)
class Currency(Switch):
pass
In another application i import the Switch, and try to add a ForeignKey to a model which inherits also from Switch
class Country(Switch):
...
currency = models.ForeignKey(Currency, on_delete=models.CASCADE)
...
.
Running makemigration or anything with manage.py i get the following error:
SystemCheckError: System check identified some issues:
ERRORS:
ads.Country.currency: (models.E006) The field 'currency' clashes with the
field 'currency' from model 'common.switch'.
Why do i get this error, and how could i resolve it? I mean, at the database level it should be only a "pointer" to the currency Model / object, and should be irrelevant to its type. Of course if i change the inheritance type of the Currency to something else, it works fine.
Django: 2.2
python: 3.5.3
.

Related

Wrong table names format - Django

I'm having an issue with the table names format of my Django project.
Here is a sample of a model I have:
class WalletHistory(models.Model):
wallet = models.ForeignKey(Wallet, on_delete=models.CASCADE, related_name='wallet_history')
free_amount = AmountField(default=None, blank=True, null=True)
locked_amount = AmountField(default=None, blank=True, null=True)
flexible_amount = AmountField(default=None, blank=True, null=True)
date_created = models.DateTimeField(auto_now_add=True, blank=True)
The app associated with this model is called core so the table name is supposed to be core_wallet_history. But Django names my table core_wallethistory instead: it doesn't split the class names with underscore.
I've changed nothing in the Django settings.
Sorry I can't post comments yet as I don't have enough reputation.
How are rendering your tables?
I use django-tables2 and all I have to change is the attributes via the class Meta under the table.
Example:
class offer_table(ExportMixin,tables.Table):
offer_name = tables.Column(accessor='offer_name')
class Meta:
attrs = {"name":"offer_table", "id":"offer_table",}

Unable to delete object from Django admin panel with MongoDB

I have a Django project using a MongoDB connected by Djongo. I created a simple model which looks like:
from django.db import models
# Create your models here.
class Property(models.Model):
name = models.CharField(max_length=128, blank=False)
property_type = models.CharField(max_length=24, blank=True)
include_on = models.CharField(max_length=256, blank=True)
format_example = models.TextField(blank=True)
notes = models.TextField(blank=True)
After registering the model by using the line admin.site.register(Property) in the admin.py file I end up seeing my model appear. After adding a test Property I see the line
The property “Property object (61226db9f4f416b206c706e5)” was added successfully.
Which tells me the item was added. It also appears on the admin panel but it looks like:
Property object (None)
If I select the property I get an error that says:
Property with ID “None” doesn’t exist. Perhaps it was deleted?
If I try to delete the property I get a ValueError with error of:
Field 'id' expected a number but got 'None'.
Since I am currently learning Django/MongoDB I actually ran across the ValueError once before. The fix was to delete the entire database and start over. The issue is I don't want to run into this in the future and want to know what I have to do to fix it, or correct what I am doing wrong.
I found my answer. Turns out I need to assign a primary key. I fixed this by changing my model to..
class Property(models.Model):
name = models.CharField(primary_key=True, max_length=128, blank=False)
property_type = models.CharField(max_length=24, blank=True)
include_on = models.CharField(max_length=256, blank=True)
format_example = models.TextField(blank=True)
notes = models.TextField(blank=True)

unique_together = (("name", "added_by"),) in Django model gives IntergretyError at/admin instead of Validation Error

I want to show a validation message like "This Project already exists" in my django admin whenever i create a project with same name.
I keep getting an IntegrityError at my Name. Isn't Django supposed to validate this and give an ValidationError if I use unique_together=((,)) in my model? Or do I have to Try and Catch the IntegrityError myself?
Also i have made two users and gave permissions to them from main admin user. so i want that one user1 cannot have projects with same name like proj1 while the user2 can have name of project as proj1.
Can anyone tell me a best practice for validating unique users inside a form/model.
models.py
class Project(models.Model):
name = models.CharField(max_length=200)
added_by = models.ForeignKey(
settings.AUTH_USER_MODEL, on_delete=models.CASCADE, blank=True, null=True, default=None)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
unique_together = (("name", "added_by"),)
def __str__(self):
return self.name

Using Model.objects.all() as a blueprint for a secondary table entry

I am having a bit of trouble with the logic of how this should work so I am hoping it is possible.
I figured out 1 possible solution that is written as an answer below, I will accept it in a few days, but if someone comes up with a better solution, I will negate any answer I post.
Overall I am working on an Apartment Move-Out/Move-In Inspection Application in Django, and in both portions I have universal Locations that must be inspected for each report. I have allowed the InspectionLocations objects to be updated/submitted by clients, which is presenting an issue in how submitted reports should be stored in my Database.
What I want is to use the InspectionLocations table as a blueprint to build an Inspection Report for Move-Ins where the form-fields are generated based on the InspectionLocations objects' location, status, and information attributes/fields.
My issue is right at this point, how do I reference those values as a blueprint to build a report submission when the number of fields in the InspectionLocations can change?
from django.db import models
from apps.units.models import Unit
class Inspections(models.Model):
class Meta:
abstract = True
id = models.AutoField(primary_key=True)
inspection_date = models.DateField()
submitted_by = models.ForeignKey(
'users.CustomUser',
default=None,
null=True,
on_delete=models.SET_NULL,
db_column='submitted_by')
last_update = models.DateTimeField(auto_now=True)
date_added = models.DateTimeField(auto_now_add=True, editable=False)
class MoveInInspections(Inspections):
unit = models.ForeignKey(Unit, on_delete=models.CASCADE, db_column='unit_id')
# should have reference to all InspectionLocation items as reference for submission, how?
class MoveOutInspections(Inspections):
unit = models.ForeignKey(Unit, on_delete=models.CASCADE, db_column='unit_id')
date_notice_given = models.DateField(blank=True, null=True, default=None)
date_vacated = models.DateField(blank=True, null=True, default=None)
# should have reference to all InspectionLocation items as reference for submission, how?
class InspectionLocations(models.Model):
'''
Defualt Inspection Locations are created when a
client is created using code like this:
InspectionLocation.objects.get_or_create(location='Living Room')
InspectionLocation.objects.get_or_create(location='Dining Room')
InspectionLocation.objects.get_or_create(location='Kitchen')
InspectionLocation.objects.get_or_create(location='Bedroom')
InspectionLocation.objects.get_or_create(location='Bathroom')
InspectionLocation.objects.get_or_create(location='Other')
'''
id = models.AutoField(primary_key=True)
location = models.CharField(max_length=50)
status = models.BooleanField(default=None)
information = models.TextField(default=None, blank=True)
I have tried ManyToMany fields and FKs but I cannot seem to get the logic working as anytime an object references an InspectionLocations object it is universally changing data for every report, which is leading be to the idea that I somehow need to use it as a blueprint.
I didn't post this in my question because it was getting long, but my best option so far seems to be to use a Django JSONField (as I am using Postgres), like so:
from django.contrib.postgres.fields import JSONField
class MoveInInspections(Inspections):
unit = models.ForeignKey(Unit, on_delete=models.CASCADE, db_column='unit_id')
data = JSONField()
class MoveOutInspections(Inspections):
unit = models.ForeignKey(Unit, on_delete=models.CASCADE, db_column='unit_id')
date_notice_given = models.DateField(blank=True, null=True, default=None)
date_vacated = models.DateField(blank=True, null=True, default=None)
data = JSONField()
To where I store the values of the InspectionLocations object's in a Dictionary

Using a class as a part of another class in django models

Assume I am writing an app to change configurations in a machine. I have 3 created tables as below. Machine configuration shows the current state of configurations for our machine. Users can create their tickets and request for changes of the configurations. RequestDetails will be the table to keep the proposed cofigurations plus some extra info such as the name of the requestor, date etc.
These classes are just a simple examples, in the real model I would have nearly 600+ fields=configuration presented in class MachineConfiguration. I should have EXACTLY THE SAME fields in RequestDetails class too. I was wondering there is a way NOT TO REPEAT MYSELF when defining class RequestDetails when it comes to all the fields that exist in MachineConfiguration model?
I want to write it in a way that if I changed anything in MachineConfiguration table, the same change would apply to RequestDetails table too.
Thanks in advance for the help.
class RequestTicket(models.Model):
subject=models.CharField(max_length=50, null=False, blank=False)
description=models.TextField(null=False, blank=True)
class MachineConfiguration(models.Model):
field_1 = models.CharField(null=False,blank=True)
field_2 = models.CharField(null=False, blank=True)
field_3 = models.CharField(null=False, blank=True)
class RequestDetails(models.Model):
tracking_number=models.ForeignKey('RequestTicket')
field_A=models.DateField(null=True, blank=False)
field_B=models.TextField(null=True, blank=False)
field_1 = models.CharField(null=False, blank=True)
field_2 = models.CharField(null=False, blank=True)
field_3 = models.CharField(null=False, blank=True)
Yes you can create the base class and inherit that class in another class like,
class BaseModel(models.Model):
field1 = models.CharField()
field2 = models.CharField()
class Meta:
abstract = True
And inherit this class in another model to get those same field,
# Now if you change any field in BaseModel, it will reflect in both the models
class MachineConfiguration(BaseModel):
pass
class RequestDetails(BaseModel):
field3 = models.CharField()

Categories

Resources