I have developed a website on Django. Initially, I used Django's default Database which is Sqlite3. Now I want to use Astra Datastax DB which is Cassandra. I am not able to convert Django.dB - models into Cassandra.cqlengine - columns function.
I have searched on the Internet and didn't find appropriate documents which could help me.
from django.db import models
from django.contrib.auth import get_user_model
from datetime import datetime
import uuid
User = get_user_model()
class Profile(models.Model):
"""docstring for Profile."""
usr: str = models.ForeignKey(User, on_delete=models.CASCADE)
id_usr: int = models.IntegerField()
Fname:str = models.TextField(blank=True,null=True)
Mname:str = models.TextField(blank=True,null=True)
Lname:str = models.TextField(blank=True,null=True)
Fhone:int = models.IntegerField(blank=True,null=True)
bio: str = models.TextField(blank=True)
img_profile = models.ImageField(
upload_to='ProfileIMG', default="blankprofile.png")
location: str = models.CharField(max_length=250)
def __str__(self):
return self.usr.username
class Post(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, unique=True)
user: str = models.CharField(max_length=100)
image = models.ImageField(upload_to="img_posts")
caption: str = models.TextField(max_length=250)
created_at = models.DateTimeField(default=datetime.now)
Likes: int = models.IntegerField(default=0)
def __str__(self):
return self.user
class LikePost(models.Model):
postid: str = models.CharField(max_length=100)
username: str = models.CharField(max_length=100)
def __str__(self):
return self.username
class Followers(models.Model):
follower: str = models.CharField(max_length=100)
user: str = models.CharField(max_length=100)
def __str__(self):
return self.user
Specially, I want to convert this into Cassandra language.
img_profile = models.ImageField( upload_to='ProfileIMG', default="blankprofile.png")
The documentation you want to consult is here: https://docs.datastax.com/en/developer/python-driver/3.25/api/cassandra/cqlengine/columns/
These are the available columns for DjangoCassandraModel, which is what you would use instead of django.db.models to get a model backed by Cassandra. You can see a basic example of connecting to DataStax Astra with django_cassandra_engine here: https://github.com/DataStax-Examples/django-cassandra-blog
As for the ImageField, I am not sure of the Django internals here, but I believe it stores a path to the file in the database after putting it on disk at the location specified ("img_posts" in your example).
You could do the same for a Cassandra backed model, or use the Blob column type to store the image data itself. There are a number of articles and examples of doing this out there.
To add to the above answer, the django_cassandra_engine package does not offer anything with the same level of automation as the ImageField found in Django's models (i.e. storing the uploaded image on local disk and saving the string path to the database, all from the field definition in the model).
What you would do is to work at a slightly lower abstraction level with an explicit (Django, pure) form. This would allow you to manually handle the file upload as outlined here: https://docs.djangoproject.com/en/4.1/ref/forms/fields/#filefield .
Once you have saved the file and have the string path to it, you can create ann istance of the corresponding Model and manually save it -- all in the appopriate view function.
As a side note, your original (sqlite-backed) code makes use of foreign keys and "on delete cascade" provision for removing related rows from other tables. This cannot be transported as is to a Cassandra storage, since the database, by itself, does not support the concept of relational integrity. You would have to decide how to handle these deletes and act on them explicitly in your code.
Related
I have a django project where I am trying to make a customer based grocery system. Here I have different databases for each customer.
Each database consist of order history as well as all other details like contact details etc.
I will get an url argument to identify customer through customer_id & I will able to get which database to use ie db name. Code -
Model -
class Company(models.Model):
company_id = models.IntegerField(primary_key = True)
name = models.CharField(max_length=256, blank=True, null=True)
db_name = models.CharField(max_length=200, blank=True, null=True)
db_uuid = models.CharField(max_length=100, blank=True, null=True)
objects = DataFrameManager()
def __str__(self):
return self.name
Views file -
#api_view(['GET', 'POST'])
def page(request, uuid):
if request.method == 'GET':
rtrn = Company.objects.filter(db_uuid=uuid).values('db_name')
return Response(rtrn)
Url file -
urlpatterns = [
url(r'user/(?P<uuid>[a-zA-Z0-9-]+)/$', page, name="getfromurl"),
]
Here I will return db name.
But I am not able to understand and implement the change of database. Let me make you understand with an example -
Lets suppose Customer name Gaurav has db 'gaurav_groceries'. By the code I get the name - gaurav_groceries. But in setting.py I have added default db as 'grocies', so how can I use this dynamic nature of db ie in this case we have 'gaurav_groceries', for further calculation and coding.
Thank you
What you are trying to do isn't trivially achieved. You may want to check out existing solutions, such as Django-multitenant which is currently the standard library used for building apps with tenanted DBs in Django.
I have below model:
class Property(models.Model):
job = models.ForeignKey(Job, on_delete=models.CASCADE)
app = models.ForeignKey(App, on_delete=models.CASCADE)
name = models.CharField(max_length=120)
value = models.CharField(max_length=350, blank=True)
description = models.TextField(blank=True)
pub_date = models.DateTimeField('date_published', default=timezone.now)
class Meta:
verbose_name_plural = "properties"
unique_together = (('value', 'name'),)
def __str__(self):
return self.name
When I try to create a Property object in admin page (I'm using Django Suit) with name/value which are already exist I get the exception: "Property with this Value and Name already exists." So it works perfect.
But in manage.py shell:
>>>from myapp.models import App, Property, Job
>>>from django.shortcuts import get_object_or_404
>>>app = get_object_or_404(App, app_name='BLABLA')
>>>job = get_object_or_404(Job, job_name='BLABLA2')
>>> Property.objects.create(job=job, app=app, name='1', value='1')
<Property: 1>
>>> Property.objects.create(job=job, app=app, name='1', value='1')
<Property: 1>
In this case I do not get any exceptions and objects are added in database.
I tried makemigrations, migrate and migrate --run-syncdb.
Django 1.9.12, sqlite3
The unique constraints are enforced at database level. You're not getting any error probably because SQLite doesn't support this type of constraint. You cannot add constraint to existing table in SQLite. If you're in early development stage, drop the table and recreate it with updated constraints. Then it should work fine in shell.
Check SQLite alter table docs for allowed updates on an existing table.
The admin form throws error because it checks uniqueness by itself without relying on database constraints.
I am making a geo django backend for an iPhone app. The iphone app sends users current location to the backend, which returns nearby restaurants (something similar to Foursquare and Yelp.)
I am not entirely sure how to store the cuisine for the restaurants. I need an option where the user can look up/select a specific cuisine for example only Chinese food. Should I create a seperate model for restaurant cuisine and have one to many relationship with the restaurants ? or should I use boolean value like this:
models.BooleanField(default=False)
Here is the code for my Model:
from django.db import models
from django.contrib.gis.db import models as gis_models
from django.contrib.gis import geos
from django.db import models
# Create your models here.
class Restaurant(models.Model):
name = models.CharField(max_length = 100)
address = models.CharField(max_length = 150)
phone = models.CharField(max_length = 12)
cuisine = models.CharField(max_length = 50)
eatingOptions = models.CharField(max_length = 50)
location = gis_models.PointField(u'Latitude/Longitude', geography=True, blank=True, null=True)
# Query Manager
gis = gis_models.GeoManager()
objects = models.Manager()
def __unicode__(self):
return self.name
Only you and your requirements can answer that.
If you create a separate model and have a relationship it will be more flexible, you can have different cuisines without changing the model. Best option if your database will have multiple types of cuisine.
If you choose to use a BooleanField like is_chinese then it will work only for chinese cuisine. This is the best option if you only care for one type of cuisine.
Don't worry if you make a bad judgement when developing (at least on an early stage), django has your back.
Hope that helps.
I'm trying to create a manager that has a method 'active_or_users' to retrieve all accounts that are active, or that an user has created. An active account has a start date that is either today, or somewhere in the past, and a end date that is somewhere in the future. Right now the active_or_users method works, however it returns duplicates of the same object. It's returning three copies of a user created active job. This is less than ideal.
from django.db.models import Q
from django.db import models
from django.contrib.auth.models import User
class ActiveJobs(models.Manager):
def active(self):
return super(ActiveJobs, self).get_query_set().\
filter(publications__publish_on__lte=date.today(),
publications__end_on__gt=date.today())
def active_or_users(self, user):
return super(ActiveJobs, self).get_query_set().\
filter((Q(publications__publish_on__lte=date.today()) &
Q(publications__end_on__gt=date.today())) | Q(creator=user))
class Job(models.Model):
title = models.CharField(max_length=100)
slug = models.SlugField(blank=True, null=True)
creator = models.ForeignKey(User)
objects = ActiveJobs()
class JobPublicationRecord(models.Model):
job = models.ForeignKey('Job', related_name='publications')
publish_on = models.DateField(auto_now=False)
end_on = models.DateField(auto_now=False, auto_now_add=False,
blank=True, null=True)
To put the comments into an answer
With the OR query, an instance will be returned for every hit of the query. I.e: an instance if a Job is created by user and another instance of the same job if also in the date range specified, etc.
So to fix this, change the method active_or_users to:
def active_or_users(self, user):
return super(ActiveJobs, self).get_query_set().filter(
(Q(publications__publish_on__lte=date.today()) &
Q(publications__end_on__gt=date.today())) | Q(creator=user)).distinct()
I build an app in django, but since I found out that google app engine doesn't support Django out of the box (free,cloud sql can't be used for free right?).
I decided to move to Django-nonrel, so there are few datebase Field that need converting, and I don't know how:
class Cate(models.Model):
name = models.CharField(max_length = 100)
description = models.TextField()
create_by = models.ForeignKey(User)
create_date = models.DateTimeField('cate created date')
def __unicode__(self):
return self.name
class Product(models.Model):
product_name = models.CharField(max_length = 200)
owner = models.ForeignKey(User)
cate = models.ManyToManyField(Cate)
timestamp = models.DateTimeField('product added date')
view = models.IntegerField(default = 0)
def __unicode__(self):
return self.product_name
here is the user_profile model which extends from user model
class UserProfile(models.Model):
user = models.OneToOneField(User)
cates = models.ManyToManyField('shop.Cate')
the Cate model is created by admin, UserProfile can have many cates, and same cate can belong to many users, same as product.
please help to construct these models and maybe some tips on how to use Django-nonrel
I am really new to database
There's two ways to do this. The cheaper version is to use ListFields
from djangotoolbox.fields import ListField
class UserProfile(models.Model):
user = models.OneToOneField(User)
cates = ListField(models.ForeignKey(shop.Cate))
The ListField simply stores a list of Cate ids. There's some important limitations to this.
Your entity is limited to 1MB, so this limits the number of entities in your list. In this case, it'll still be a fairly large number, especially since there's nothing else in your entity.
You can do dataastore queries against the cates field if it's indexed. However, each entity has a limit of 5000 indexes. You'll use one for the user attribute, so in this case, your cates list will be limited to have 5000 entries. I haven't hit this before so I don't know how it would fail, I presume you'd get an exception on writing your entity.
The more expensive option is to use an intermediate mapping entity. This gives you unlimited relations for the extra expense of creating/querying the mapping entities.
class UserCateMapping(models.Model)
user = models.ForeignKey(UserProfile)
cate = models.ForeignKey(Cate)
In this case, you'll need to create a new entity for each relation, and query for the UserCateMapping entities before fetching the actual Cate or UserProfile entity you actually want to use. It's going to be more costly than the first option, but you'll have unlimited mappings.