Django data types vs. MySQL types - python

I'm new in Django. It is possible to compare Django data types to MySQL types?
I have for example this, and I want to create a table with it's arguments (usin MySQL commands). It should be possible to work with the database using Django.
class Produkt(models.Model):
je_aktivny = models.BooleanField(default=False)
nazov = models.CharField(max_length=255, default='', db_index=True)
popis = models.TextField(default='')
popis_kratky = models.TextField(default='')
So I know, that the table will be 'Produkt'.
But what columns are equal to this attributes? I want to make a table which would be equal to class Produkt. Is it possible?
My try is:
CREATE TABLE Produkt(je_aktivny TINYINT, nazov CHAR(255), popis TEXTFIELD, popis_kratky TEXTFIELD)
But I'm not sure. Will you give me an advice?

You don't need to know this. The whole point of creating a model first is that you can then automatically create the table by running manage.py syncdb.

Related

Django models' best solution for this reverse ForeignKey

I'm making a personal project to manage restaurants.
Two of my models are facing a problem, these models are DiningRoom and Table.
DiningRoom is the representation of any area that the restaurant could have (e.g. we could have one area inside and other area in the terrace of the building).
And in every DiningRoom we can set a layout of Tables.
So, the more object-oriented way I find to map this is by many-to-one relationship (ForeignKey). Since one DiningRoom can have many Tables, and one Table can be only in one DiningRoom. Right?
So my models are:
class DiningRoom(models.Model):
account = models.ForeignKey(Account, on_delete=models.CASCADE, null=False)
name = models.CharField(max_length=50, null=False, blank=False)
rows = models.IntegerField(max=15, null=False)
cols = models.IntegerField(max=15, null=False) # rows and columns are for the room's grid layout.
class Table(models.Model):
row = models.IntegerField(max=15, null=False) # The row in the room's grid where the table is at.
col = models.IntegerField(max=15, null=False) # the column in the room's grid where the table is at.
dining_room = models.ForeignKey(DiningRoom, on_delete=models.CASCADE, null=False) # Here is the problem.
The problem is that when I am querying DiningRooms of the account in the view, I need to fetch also the Tables that are related to each DiningRoom in the queryset result.
def dining_rooms(request):
try:
account = Account.objects.get(id=request.session['account_id'])
except Account.DoesNotExists:
return response(request, "error.html", {'error': 'Account.DoesNotExists'})
dining_rooms = DiningRoom.objects.filter(account=account)
But also I need the Tables of the results in dining_rooms!
I found two possible solutions but none seem to be "correct" to me. One is to make a Many-to-many relationship and validate that any Table is only in one DiningRoom in the view. And the second and worse one could be fetching the Tables once for each DiningRoom obtained in the queryset (but imagine a restaurant with 5 or 6 different areas (DiningRooms), it would be needed to fetch the database six times for every time).
Doing it in vice-versa and fetching all the Tables and select_related DiningRooms is not possible since it's possible to have a DiningRoom with no Tables in it (and in this case we will have missing DiningRooms).
What could be the best way to handle this? Thanks!
You can use the related_name or relationships backwards, an acceptable solution would be to create a method in the DiningRoom model that is called associated_tables() and return using the related_name (modelname_set, in this case it would be table_set). It is the name of the lowercase child model followed by the suffix _set
class DiningRoom(models.Model):
#your fields
def associated_tables(self):
return self.table_set.all()
In addition, this video tutorial could clear your days and give you a better idea about reverse relationships:
https://youtu.be/7tAZdYRA8Sw

Django - IntegrityError in terminal when migrating changes to a relationship field

I've got a Django model like the following..
class ExampleModel(models.Model):
name = models.CharField(...)
related_user = models.ForeignKey(UserTypeA, related_name='related_example', blank=True, null=True, on_delete=models.SET_NULL)
where I recently had to make a change to the related_user field by changing the ForeignKey from UserTypeA to UserTypeB.
Of course, this raises an error in the terminal when I attempt to python manage.py makemigration...
django.db.utils.IntegrityError: insert or update on table "models_examplemodel" violates foreign key constraint "models_examplemodel_related_user_id_ac0c6018_fk_accounts_"
DETAIL: Key (related_user_id)=(13) is not present in table "accounts_usertypea".
What's the safest way to go about making these changes? Currently I'm in development so I'm happy to delete my data/migrations/whatever, but I imagine in production this would be difficult.
The ideal behaviour I'd like to see here is the relations from ExampleModel and UserTypeA just being deleted, and so the current relationships would be set to NULL. Thoughts?
if you simply want to drop UserTypeA and use UserTypeB with None values simply do this:
remove related_user field
generate migrations
add related_user field
generate migrtions
If you want to do something more complecated (fill UserTypeB based on UserTypeA) these are the steps
add realted_user_b field with default as null
generate migration file
write a data migrations file which fills realted_user_b based on current data docs
remove realted_user field
generate migration file
rename realted_user_b to realted_user
generate migration file

onetoone database relation between two tables?

I have 4 tables already exist in system.
Account
Project
document
Catalog
There are many Accounts in the system and each Account many have many Projects, each project have many documents.
[Current system not handle same project name in a different Accounts]
catalog Table:
class catalog(models.Model):
catalog_name = models.TextField(blank=True, null=True)
documents = models.ManyToManyField(document, blank=True, null=True)
Current system map documents of any project in the Catalog table.
We create catalog_name by project_name and add documents in the document
So Project name can not be repeated.
Project Table:
class Project(models.Model):
FK_Account = models.ForeignKey(Account, blank=True, null=True)
Project_ID = models.TextField(blank=True, null=True, db_index=True)
Project_Name = models.TextField(blank=True, null=True, db_index=True)
document Table:
class document(models.Model):
uid = models.TextField(blank=True, null=True,db_index=True)
Code to get Project documents:
def getAllProjectDocument(self, project_obj, current_selected_option='All'):
""" Returns All Project Documents. """
docs = []
cat_obj_list = catalog.objects.filter(catalog_name = project_obj.Project_Name + "-user-catalog")
if cat_obj_list:
catobj = cat_obj_list[0]
if current_selected_option=="All":
docs = catobj.documents.filter(status=2)
else:
docs = catobj.documents.filter(status=2, publish_status=int(current_selected_option))
return docs
Note: status 2 means document is any on project.
There are 950000 documents and 300000 projects in the system. If I have to get project documents of the of all project then I have to query on the catalog table for each project i.e. 300000 time and again do filtering in according to search and then add query set objects to python list and pass to template after finishing for loop
So for loop is running for 300000 times then query on catalog for same count i.e. 300000 and filter again same count i.e. ``300000` . So apache memory is increases.
I come with following idea : This is migration of Database.
I am going to create table which have one to one mapping og project and document.
There are are 4 types of document- 1. Private, 2. Project, 3. Library, 4. Delete document.
class Project_Document(models.Model):
FK_Project = models.ForeignKey(Project, blank=True, null=True)
FK_Dcoument = models.ForeignKey(document, blank=True, null=True)
So is **onetoone mapping is correct or anyone have different way to do this?**
Your ProjectDocument table is really just a many-to-many relationship, exactly as you already have between Catalog and Document. I don't think adding another one would really help, especially as you would then have to ensure the two relationships are kept in sync.
Instead you should add the missing relationship directly between Catalog and Project; I can't tell from the code whether that should be a one-to-many (ForeignKey) or one-to-one, and if the former which direction it should go. But assuming each Project has multiple Catalogs, you would add a ForeignKey on Catalog pointing at Project; then you could get all the Documents for a Project with one query:
project_docs = Document.objects.filter(catalog__project=my_project)
Note also you have some big inefficiencies in your table; you seem to be using TextFields throughout, which are stored as blobs in the database, and therefore have a massive overhead. You should be using CharFields for things like IDs and names; TextFields are only for large blocks of text such as the body content of a document itself.

Retrieve the subset of fields by querying the embedded field

Is it possible to retrieve the subset of fields using Django mongodb nonrel. I am totally new to python, but have good knowledge in mongo.
My requirement is very straight forward, I wanted to query the collection by its embedded field and return only some specific fields
I could do that in mongodb by
db.Contract.find({'owner.name':'Ram'},{'address':1})
and I tried this in django
Contract.objects.filter(owner__name='Ram')
but it throws an error
raise FieldError("Join on field %r not permitted. Did you misspell %r
for the lookup type?" % (name, names[pos + 1])) FieldError: Join on
field 'owner' not permitted. Did you misspell 'name' for the
lookup type?
am totally struck here. I believe i have my models as specified in the documentation.
class SimplePerson(models.Model):
name = models.CharField(max_length=255)
user_key = models.CharField(max_length=255)
class Contract(models.Model):
owner = EmbeddedModelField('SimplePerson')
title = models.CharField(max_length=120, )
This is really weird. I could't find any reference in the documentation site about how to query the embedded field & retrieve the subset of fields.
Finally I used raw_query to query the embedded field
Contract.objects.raw_query({'owner.name':'Ram'})
But still not able to figure out how to retrieve the subset of fields. Can someone help me out?
Subobject filters aren't possible yet so you need to drop down to raw_query (which you already figured out). To retrive a subset of fields, use .values('field1', 'field2', ...).
Filtering by EmbeddedField is now possible with the following syntax:
Contract.objects.filter(owner={'name': 'Ram'})

django save data in database only when certain conditions are met

I have a python function that scrapes some data from a few different websites and I want to save that data into my database only if a certain condition is met. Namely, the scraped data should only be saved if the combination of the location and date field is unique
So in my view I have a new location variable and and date variable and essentially I just need to test this combination of values against what's already in the database. If this combination is unique, then save it. If it's not, then do nothing.
class Speech(models.Model):
location = models.ForeignKey(Location)
speaker = models.CharField(max_lenth=100)
date = models.DateField
I'm pretty new to django so I'm just not sure how to go about executing this sort of database query.
You want a combination of two things. First, you want a inner Meta class to enforce the uniqueness in the database:
class Speech(models.Model):
location = models.ForeignKey(Location)
speaker = models.CharField(max_length=100)
date = models.DateField()
class Meta:
unique_together = ('location', 'date')
Then, when you're doing your data manipulation in your view, you want the get_or_create method of the default model manager:
speech, new = Speech.objects.get_or_create(
location=my_location_string,
date=my_datetime_variable,
)
if new:
speech.speaker = my_speaker_string
speech.save()
I hope that gets you started. As always, you know your needs better than I do, so don't blindly copy this example, but adapt it to your needs.
Documentation:
unique_together
get_or_create

Categories

Resources