PostGIS geography does not support the "~=" function/operator - python-3.x

I am trying to save point field in the database via update_or_create method but it is giving me this error.
My function to save data:
for city in cities_data:
obj, created = models.City.objects.update_or_create(
name = city["name"],
country = city["country"],
state = city["state"],
point = Point(
float(city["longitude"]),
float(city["latitude"])
),
radius = city["radius"],
is_curated = city["is_curated"],
is_metro_city = city["is_metro_city"]
)
obj.save()
Model:
class City(models.Model):
name = models.CharField(max_length=50)
country = models.CharField(max_length=50)
state = models.CharField(max_length=50)
point = gis_models.PointField(geography=True, null=True)
is_metro_city = models.BooleanField(default=False)
is_curated = models.BooleanField(default=False)
radius = models.IntegerField(null=True)
when I try to run this I get this error:
ValueError: PostGIS geography does not support the "~=" function/operator.
I want to know why I am getting this error, I did not find any useful information related to this. Thanks in Advance.

If you want to use this you can use it like this:
obj, created = models.City.objects.update_or_create(
**city_data,
defaults={'point': Point(
float(city["longitude"]),
float(city["latitude"])
)}
)
I do not know why it does not work that way, but I made it work this way, if you find it out why it does not work you can improve the answer.

I have the same error and the problem was that I have a unique together constraint in model's class Meta eg:
class Meta:
unique_together = 'name', 'geom'
After deleting it, the error disappears although you must check by yourself if you need such constraint.

Related

Django Aggregate Between Timezone Aware Fields

I want to find the average time between two dates - 'created_date' and 'modified_date'. Both are DateTimeField and values are timezone aware.
Color Model:
name = models.CharField(max_length=150)
is_published = models.BooleanField(default=False)
created_date = models.DateTimeField(null=True, blank=True)
modified_date = models.DateTimeField(null=True, blank=True)
To Save:
example.created_date = datetime.datetime.now(tz=timezone.utc)
example.save()
I ran the below query:
avg_change = Color.objects.filter(is_published=True, created_date__isnull=False, modified_date__isnull=False).aggregate(avg_score=Avg(F('modified_date') - F('created_date')))
I got the error below.
if dt.tzinfo is not None:
AttributeError: 'decimal.Decimal' object has no attribute 'tzinfo'
I'm on Python3.6/Django2.2/mysql 5.7.
I'm not sure if I need to change the values to naive and then aggregate. What am I missing? Any viable route to approach this as I am not good with raw SQL.
I later did this:
from django.db.models import F, ExpressionWrapper
from django.db import models
avg_duration = ExpressionWrapper(F('modified_date') - F('created_date'), output_field=models.DurationField())
avg_change = Color.objects.filter(is_published=True, created_date__isnull=False, modified_date__isnull=False).aggregate(avg_score=Avg(avg_duration))
If you know of a more better option kindly share.

Django models filter query not recognising field

I am working on a Django project, filter query function is not working as expected
I imported the model, did migration
I don't understand where the code is wrong, it is not able to recognize the field (rating)
Model I created
class Problem(models.Model):
contestID = models.IntegerField()
index = models.CharField(max_length=5)
name = models.CharField(max_length=50)
rating = models.IntegerField(default=0)
link = models.URLField(max_length=200)
tags = models.ManyToManyField(Tag,blank=True,related_name="Problme")
My code in views: ( object.all() is working properly but the filter is not working)
def fetchProblems(min = 0, max = 5000, filter = False):
if not filter:
problemSet = Problem.objects.all().values()
else:
problems = Problem.objects.filter(rating < max,rating > min)
return problemSet
My error : ( rating not defined) (basically I tried all fields it shows all not defined)
NameError: name 'rating' is not defined
Thank you for help
The correct syntax is
.filter(rating__gt=min)
You can find out more about the various lookup types (separated by double underscores) over at https://docs.djangoproject.com/en/3.2/topics/db/queries/#field-lookups

Django Foreign key to not loaded object

Hello I have a problem that I want to link foreign key to model's related object in other words I want to link foreign key to not loaded object's fields.
class Category(models.Model):
...
filter_option_content_type = models.ForeignKey(ContentType, on_delete=models.SET_NULL, limit_choices_to=(
models.Q(app_label='catalog', model='FrameSize') |
models.Q(app_label='catalog', model='ShoeSize') |
models.Q(app_label='catalog', model='ClothSize')
), null=True)
...
class Product(models.Model):
...
category = models.ForeignKey(Category, on_delete=models.SET_NULL, null=True)
...
class ProductItem(models.Model):
...
model = models.ForeignKey(Product, verbose_name='Модель', on_delete=models.CASCADE, related_name='productitem')
size = models.ForeignKey('model.category.filter_option_content_type', on_delete=models.SET_NULL, null=True)
...
And sure i got this error:
ValueError: Invalid model reference 'model.category.filter_option_content_type'. String model references must be of the form 'app_label.ModelName'
is it possible to do relation like this wtihout using GenericForeignKey instead of ForeignKey?
I think that you don't really need to add an additional relation since you can access the field you want via Product:
item = ProductItem()
size = item.model.category.filter_option_content_type
In case you'd like to query using this field, it would look like:
item = ProductItem.objects.filter(
model__in=Product.objects.filter(
category__in=Category.objects.filter(
filter_option_content_type='<your desired value of size>'
)
)
)
Since the relations are based on Foreign Keys which are indexed - such query shouldn't have a noticeable effect on performance (despite that it may seem a bit awkward)

FactoryBoy: How do I define a factory field for a generic foreign key?

Since the type of a generic foreign key object is not know until a record is created in the model, what sub factory do I define it as ? Or is there another way to approach this ?
models.py
class Contract(models.Model):
offer_type = models.ForeignKey(ContentType, on_delete=models.PROTECT)
offer_id = models.PositiveIntegerField()
offer = GenericForeignKey('offer_type', 'offer_id')
invoice = models.ForeignKey('Invoice', on_delete=models.PROTECT)
status = models.CharField(max_length=8)
commission = models.DecimalField(max_digits=100, decimal_places=2)
factories.py
class ContractFactory(factory.DjangoModelFactory):
class Meta:
model = models.Contract
#What to do here ???
offer = factory.SubFactory(????)
invoice = factory.SubFactory(InvoiceFactory)
status = 'active'
commission = 40.00
Somehow you have to pass what kind of model you're willing to see
(if not random)
so your proposal is good for one choice, but for a more generic approach
use this:
class BaseContractFactory(dj_factory.DjangoModelFactory):
class Meta:
model = Contract
exclude = ['offer']
offer_id = factory.SelfAttribute('offer.id')
offer_type = factory.LazyAttribute(
lambda obj: ContentType.objects.get_for_model(obj.offer)
)
...
class Concrete1ContractFactory(BaseContractFactory):
offer = factory.SubFactory(Concrete1Factory)
class Concrete2ContractFactory(BaseContractFactory):
offer = factory.SubFactory(Concrete2Factory)
where Concrete1 and Concrete2 are some existing Django models

Mongoengine Link to Existing Collection

I'm working with Flask/Mongoengine-MongoDB for my latest web application.
I'm familiar with Pymongo, but I'm new to object-document mappers like Mongoengine.
I have a database and collection set up already, and I basically just want to query it and return the corresponding object. Here's a look at my models.py...
from app import db
# ----------------------------------------
# Taking steps towards a working backend.
# ----------------------------------------
class Property(db.Document):
# Document variables.
total_annual_rates = db.IntField()
land_value = db.IntField()
land_area = db.IntField()
assessment_number = db.StringField(max_length=255, required=True)
address = db.StringField(max_length=255, required=True)
current_capital_value = db.IntField
valuation_as_at_date = db.StringField(max_length=255, required=True)
legal_description = db.StringField(max_length=255, required=True)
capital_value = db.IntField()
annual_value = db.StringField(max_length=255, required=True)
certificate_of_title_number = db.StringField(max_length=255, required=True)
def __repr__(self):
return address
def get_property_from_db(self, query_string):
if not query_string:
raise ValueError()
# Ultra-simple search for the moment.
properties_found = Property.objects(address=query_string)
return properties_found[0]
The error I get is as follows: IndexError: no such item for Cursor instance
This makes complete sense, since the object isn't pointing at any collection. Despite trolling through the docs for a while, I still have no idea how to do this.
Do any of you know how I could appropriately link up my Property class to my already extant database and collection?
The way to link a class to an existing collection can be accomplished as such, using meta:
class Person(db.DynamicDocument):
# Meta variables.
meta = {
'collection': 'properties'
}
# Document variables.
name = db.StringField()
age = db.IntField()
Then, when using the class object, one can actually make use of this functionality as might be expected with MongoEngine:
desired_documents = Person.objects(name="John Smith")
john = desired_documents[0]
Or something similar :) Hope this helps!
I was googling this same question and i noticed the answer has changed since the previous answer:
According to the latest Mongoengine guide:
If you need to change the name of the collection (e.g. to use MongoEngine with an existing
database), then create a class dictionary attribute called meta on your document, and set collection to the
name of the collection that you want your document class to use:
class Page(Document):
meta = {'collection': 'cmsPage'}
The code on the grey did the trick and i could use my data instantly.

Resources