Python/Django: Create table with two primary_key using cql engine - django

I want create a table with two primary_key by it's django model as below:
class UserView(Model):
email= columns.Text(primary_key=True)
entryLink= columns.Text(primary_key=True)
date= columns.Date(default=datetime.date.today())
but when I want create table as below:
>>> from cqlengine import connection
>>> from cqlengine.management import create_table
>>> from MainAPP.models import UserView
>>> connection.setup(['127.0.0.1:9160'])
>>> create_table(UserView)
I see this error:
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "H:\Web-Programming\Python\Project\Prexter\Virtual-Environment\Lib\site-packages\cqlengine\management.py", line 97, in create_table
execute(qs)
File "H:\Web-Programming\Python\Project\Prexter\Virtual-Environment\Lib\site-packages\cqlengine\connection.py", line 172, in execute
return connection_pool.execute(query, params)
File "H:\Web-Programming\Python\Project\Prexter\Virtual-Environment\Lib\site-packages\cqlengine\connection.py", line 164, in execute
raise CQLEngineException(unicode(ex))
CQLEngineException: Bad Request: Missing CLUSTERING ORDER for column entryLink
When I remove primary_key property from entryLink field, I have no error! but I want define entryLink as a primary_key! What is my mistake?

A database table cannot have 2 primary key. If you are looking for a Composite Primary Key, Django does not support that yet.
Now, what you might be looking for is unique=True (a candidate key).
class UserView(Model):
email= columns.Text(primary_key=True)
entryLink= columns.Text(unique=True)
date= columns.Date(default=datetime.date.today())
You can also read this post for a better understanding

I found My Answer! This is a funny bug!
I have a capitalized character among entryLink field, and it caused considered error! This is so funny! because this applies to primary_key only! and it isn't true about other fields!!! primary_keys can't have a capitalized character among!
My modified code:
class UserView(Model):
email= columns.Text(primary_key=True)
link= columns.Text(primary_key = True)
date= columns.Date(default=datetime.date.today())

Related

Get Bounding Box from Django PolygonField

I am trying to get the bounding box for a PolygonField in a Django model. I read here that you can use extent but when running the below as per the extent documentation:
qs = newJob.objects.filter(pk=1).aggregate(Extent('loc'))
print(qs['loc__extent'])
I get the error:
Traceback (most recent call last): File
"/usr/local/lib/python3.9/site-packages/django/db/backends/utils.py",
line 86, in _execute
return self.cursor.execute(sql, params) psycopg2.errors.UndefinedFunction: function st_extent(geography) does
not exist LINE 1: SELECT ST_Extent("app_newjob"."loc") AS
"loc__ext...
^ HINT: No function matches the given name and argument types. You might need to add explicit type casts.
My model (simplified) looks like this:
from django.contrib.gis.db import models
class newJob(models.Model):
name = models.CharField(max_length=64)
desc = models.CharField(max_length=64)
loc = models.PolygonField()
And in my test:
from django.contrib.gis.db.models import Extent
newJob.objects.create(
name="test",
desc="test",
loc="SRID=4326;POLYGON ((0.9063720703125029 52.32023207609735, 0.8239746093749998 52.10819209746323, 1.170043945312496 52.14191683166823, 1.170043945312496 52.31351619974807, 0.9063720703125029 52.32023207609735))"
)
qs = newJob.objects.filter(pk=1).aggregate(Extent('loc'))
print(qs['loc__extent'])
I'm running a PostGIS database on the back.
Any ideas what I'm doing wrong?

Django Object is Not Serializable CommandError using Dumpdata with Natural Keys

I am trying to use 'natural keys' for serialization (docs) in a "manage.py dumpdata" command:
python manage.py dumpdata --natural-primary --natural-foreign --indent 4 --format json --verbosity 1 > tests\test_fixtures\test_db2.json
and I am getting the following error when I use --natural-foreign on other apps that use the Project or Task model (which they all must by design):
CommandError: Unable to serialize database: Object of type Project is not JSON serializable
Exception ignored in: <generator object cursor_iter at 0x000001EF62481B48>
Traceback (most recent call last):
File "C:\Users\Andrew\anaconda3\envs\Acejet_development\lib\site-packages\django\db\models\sql\compiler.py", line 1586, in cursor_iter
cursor.close()
sqlite3.ProgrammingError: Cannot operate on a closed database.
If I just dumpdata from this, the 'projects' app, it works, but other apps are built with entities related to Project or Task and there the --natural-foreign option fails.
The problem occurs when a model (say Question) calls for a natural_key from Task, which includes a for a natural_key from Project.
If I use the Pycharm Python Console to access querysets of Projects or Tasks ('q' here), this works:
serializers.serialize('json', q, indent=2, use_natural_foreign_keys=True, use_natural_primary_keys=True)
But if 'w' is a list of Question objects from another app that have a Task foreign key I get this error:
Traceback (most recent call last):
File "<input>", line 1, in <module>
File "C:\Users\Andrew\anaconda3\envs\Acejet_development\lib\site-packages\django\core\serializers\__init__.py", line 128, in serialize
s.serialize(queryset, **options)
File "C:\Users\Andrew\anaconda3\envs\Acejet_development\lib\site-packages\django\core\serializers\base.py", line 115, in serialize
self.end_object(obj)
File "C:\Users\Andrew\anaconda3\envs\Acejet_development\lib\site-packages\django\core\serializers\json.py", line 53, in end_object
json.dump(self.get_dump_object(obj), self.stream, **self.json_kwargs)
File "C:\Users\Andrew\anaconda3\envs\Acejet_development\lib\json\__init__.py", line 179, in dump
for chunk in iterable:
File "C:\Users\Andrew\anaconda3\envs\Acejet_development\lib\json\encoder.py", line 431, in _iterencode
yield from _iterencode_dict(o, _current_indent_level)
File "C:\Users\Andrew\anaconda3\envs\Acejet_development\lib\json\encoder.py", line 405, in _iterencode_dict
yield from chunks
File "C:\Users\Andrew\anaconda3\envs\Acejet_development\lib\json\encoder.py", line 405, in _iterencode_dict
yield from chunks
File "C:\Users\Andrew\anaconda3\envs\Acejet_development\lib\json\encoder.py", line 325, in _iterencode_list
yield from chunks
File "C:\Users\Andrew\anaconda3\envs\Acejet_development\lib\json\encoder.py", line 438, in _iterencode
o = _default(o)
File "C:\Users\Andrew\anaconda3\envs\Acejet_development\lib\site-packages\django\core\serializers\json.py", line 104, in default
return super().default(o)
File "C:\Users\Andrew\anaconda3\envs\Acejet_development\lib\json\encoder.py", line 179, in default
raise TypeError(f'Object of type {o.__class__.__name__} '
TypeError: Object of type Project is not JSON serializable
The models are:
# projects.models.py
class BaseModelWithHistory(models.Model):
history = HistoricalRecords(inherit=True)
natural_key_fields = ('id',) # default
class Meta:
abstract = True
def natural_key(self):
fieldlist = [getattr(self, fieldname) for fieldname in self.natural_key_fields]
return tuple(fieldlist)
# natural_key.dependencies = ['projects.Project', 'projects.Task'] # serialize these first.
class Project(BaseModelWithHistory):
"""
'Projects' group Tasks.
"""
project_name = models.CharField(max_length=200, default="development_project")
project_short_description = models.CharField(
max_length=500,
default="This is the default text.")
target_group = models.ManyToManyField(Group, blank=True)
objects = ProjectDiscreteManager()
natural_key_fields = ('project_name',)
class Task(BaseModelWithHistory):
number = models.PositiveIntegerField(default=0)
name = models.CharField(max_length=200, default='new task')
project = models.ForeignKey(Project, on_delete=models.CASCADE)
target_group = models.ManyToManyField(Group, blank=True)
app_label = models.CharField(max_length=80, choices=app_choices(), null=True, blank=True)
objects = discrete_manager_factory('project')
natural_key_fields = ('project', 'name', 'number')
Things that I wouldn't expect to cause this problem but I could certainly be wrong:
The ProjectDiscreteManager and others created by discrete_manager_factory() behave exactly as the default manager (models.Manager()), unless its called with a request from an identified user, in which case it adds a filter to see if that user is in the Group.
All models define the natural_keys tuple because the parent class defines it as ('id',); most models overwrite this with more representative fields.
With the natural_key.dependencies list set for all models to prioritize Project and then Task, I get a 'can't resolve dependencies' error for every other model. I think this ticket relates, but am not sure how to track down whether this fix is already in the Django 3.0.6 I'm using and I should just straighten up & fly right, or if my Han Solo 'this should wooork' will one day soon be rewarded. [Update: I worked out it is coming in Django 3.1.1, but I'm not sure that it is going to fix the "can't resolve dependencies" error I've created for myself.]

Django: What is the correct way to query by foreign key field's id?

I have two models:
class Organization(models.Model):
title = models.CharField(max_length=100)
class Folder(models.Model):
organization = models.ForeignKey("Organization",related_name='folders')
title = models.CharField(max_length=50)
Now I want to filter the folder by organization id. so I tried:
Folder.objects.filter(organization= 1)
Folder.objects.filter(organization_id= 1)
Folder.objects.filter(organization__id= 1)
Folder.objects.filter(organization__pk= 1)
Folder.objects.filter(organization= Organization.objects.get(id=1))
Believe it or not everything returns the same.
So anybody know what is the correct way to query by foreign key field's id?
update
but when try to create folder by:
Folder.objects.create(organization__id=1,title='hello')
got error:
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/home/suhail/.virtualenvs/heybadges/local/lib/python2.7/site-packages/django/db/models/manager.py", line 92, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/home/suhail/.virtualenvs/heybadges/local/lib/python2.7/site-packages/django/db/models/query.py", line 370, in create
obj = self.model(**kwargs)
File "/home/suhail/.virtualenvs/heybadges/local/lib/python2.7/site-packages/django/db/models/base.py", line 452, in __init__
raise TypeError("'%s' is an invalid keyword argument for this function" % list(kwargs)[0])
TypeError: 'organization__id' is an invalid keyword argument for this function
but Folder.objects.create(organization_id=1,title='hello') works fine.
Django docs say that you should use Folder.objects.filter(organization__pk=1) in most cases.
Answer to the update:
Probably Folder.objects.create(organization_id=1,title='hello') works because Django appends "_id" to the field name to create its database column name.

Django get method is yielding an error

I'm following a Django book (Django 1.0 Web Site Development). I'm finding that the book, although straight forward and easy to read, leaves out small details. However, this error that I'm getting, I have not been able to find a solution online. Thanks for any help.
Below, I added the Tag class to my models.py file.
from django.db import models
from django.contrib.auth.models import User
class Link(models.Model):
url = models.URLField(unique=True)
class Bookmark(models.Model):
title = models.CharField(max_length=200)
user = models.ForeignKey(User)
link = models.ForeignKey(Link)
class Tag(models.Model):
name = models.CharField(max_length=64, unique=True)
bookmarks = models.ManyToManyField(Bookmark)
Then I attempt to run the following code at the python shell:
from bookmarks.models.import *
bookmark = Bookmark.objects.get(id=1)
As a result, I get the following error:
Traceback (most recent call last):
File "(console)", line 1, in (module)
File "c:\Python27\lib\site\-packages\django\db\models\manager.py", line 132, in get
return self.get_query_set().get(*args, **kwargs)
File "c:\Python27\lib\site-packages\django\db\models\query.py", line 349, in get
% self.model._meta.object_name)
DoesNotExist: Bookmark matching query does not exist.
The error means just what it says. DoesNotExist is raised by QuerySet.get() if there is no object in the database that would match the conditions given to the QuerySet. In this case it means there is no Bookmark object in the database with an ID equal to 1.
Did you add any data in the Bookmark table yet? DoesNotExist is raised by get if there is no record corresponding to your query. i.e. if there is no record corresponding to id=1.

django add_to_class() making models inheritance/MRO work wrong

I have a problem with inheritance on my models when adding fields via add_to_class().
I have a models File(models.Model) and Image(File) - these come from django-filer.
In my app I'm importing them and adding fields and methods:
def method_x(self):
print "x"
File.add_to_class("expiration_date", models.DateField(null=True, blank=True))
File.add_to_class("method_x", method_x)
Image should inherit both of those but it gets only the method(s), not field(s):
>>> some_file = File.objects.get(id=8)
>>> some_image = Image.objects.get(id=8)
>>>
>>> print some_file.expiration_date # this works
... None
>>>
>>> some_image.metgod_x() # this works
>>> x
>>>
>>> print some_image.expiration_date # and this not
Traceback (most recent call last):
File "<console>", line 1, in <module>
AttributeError: 'Image' object has no attribute 'expiration_date'
Any clue?
Your model's add_to_class does not add the field as an attribute. it just calls contribute_to_class on your field:
django/db/models/base.py#L218
Your field's contribute_to_class does not do it either. It just adds the field to the model's _meta member: django/db/models/fields/__init__.py#L234