In variable called object_type I store values like: Profile or Company which are names of models available in the app. Both models has field called uuid.
I need to something like this:
get_object_or_404(object_type, uuid=uuid_from_request)
how can I pass object_type value (Profile or Company) to query correct model?
How about using a dictionary that map model names to model classes:
object_types = {'Profile': Profile, 'Company': Compnay}
...
get_object_or_404(object_types[object_type], uuid=uuid_from_request)
Or using getattr:
import app.models
get_object_or_404(getattr(app.model, object_type), uuid=uuid_from_request)
In django all model types are stored in magical cache, so you might use this cache to get model types, like that:
from django.db.models.loading import get_model
Model = get_model("your_app_name", "Profile")
get_object_or_404(object_type, uuid=uuid_from_request)
Related
How can we create a model record or object using another object.
get_object = my_model.objects.filter(id=1)
I want to do something like below to create object in another database
my_model.objects.using('DB2').create(my_model=get_object)
You can overide save method or use django signals, based on your requirements.
You can use the code below to replicate the object to the model in another database having same fields.
get_object = my_model.objects.filter(id=1).values().first()
get_object.update({'id': None})
my_model.objects.using('DB2').create(**get_object)
You can get yours model as dict and unpack it to new model object.
from users.models import User, AnotherUser
from django.forms.models import model_to_dict
old_user = User.objects.get(pk=1)
data = model_to_dict(old_user, fields=['username', 'email'])
new_user = AnotherUser.objects.using('DB2').create(**data)
Its better to not copy pk(id) but provide this to database by itself
With a database model described in the simplified toy example below, we are trying to get a list of EAV attributes used for a specific Product.
The sample source code in the Actions section below serves the purpose; however, we feel the statement is overly verbose: We only need columns of the template_attribute table, but the values arguments need to maintain a fully qualified path starting from the original Product model. See the code below:
# Getting the `id` columns from multiple-orders of related models:
attribute_set = template. values(
"id", # the base model, Product
"template__id", # the related model, Template
"template__templateattribute__id" # the second related model, TemplateAttribute
)
So, we wonder if there is a way to refer to the columns directly from the containing model, e.g. templateattribute__id, or even better id, instead of template__templateattribute__id.
We are new to the Django ORM and appreciate any hints or suggestions.
Actions:
template = Product.active_objects.filter(id='xxx').select_related('template')
attribute_set = template. values("id", "template__id", "template__templateattribute__id")
for i, attr in enumerate(attribute_set):
print("{:03}: {}".format(i, attr))
# Output:
# 000: {'id': xxx, 'template__id': xxxx, 'template__templateattribute__id': xxxxx}
# 001: {'id': xxx, 'template__id': xxxx, 'template__templateattribute__id': xxxxx}
# 002: {'id': xxx, 'template__id': xxxx, 'template__templateattribute__id': xxxxx}
# ...
The models:
# Simplified toy example
class Product(models.Model):
product_template = models.ForeignKey(Template)
sku = models.CharField(max_length=100)
...
class Template(models.Model):
base_sku = models.CharField(max_length=100)
...
class TemplateAttribute(models.Model):
product_template = models.ForeignKey(Template)
attribute = models.ForeignKey(eav_models.Attribute)
...
# From the open-source Django EAV library
# imported as `eav_models`
#
class Attribute(models.Model):
name = models.CharField(_(u"name"), max_length=100,
help_text=_(u"User-friendly attribute name"))
...
slug = EavSlugField(_(u"slug"), max_length=50, db_index=True,
help_text=_(u"Short unique attribute label"))
...
Perhaps using a Manager with annotations or aliases could help?
You could try to add more magic by trying to dynamically add an annotation for each key during the manager's construction, but really at that point you are writing code that should have been in the EAV itself.
I would warn you, having attribute names and their values in a table instead of just model fields (and columns in the DB) will be an uphill battle, and already you are finding areas where your library isn't handling things for you.
from django.db import models
from django.db.models import F
class ProductManager(models.Manager):
def get_queryset(self):
qs = super().get_queryset() \
.annotate(
my_attribute_key=F('template__templateattribute__id')
)
return qs
In addition, we also figured out a workaround by defining a base path:
base = "template__templateattribute"
So, instead of
attribute_set = template. Values("template__templateattribute__id")
, we can do the following:
attribute_set = template. Values(base+"__id")
This is just an informal workaround, though. The better way is still to use a Manager class.
I've successfully used Graphene-Django to successfully build several GraphQL calls. In all of those cases I populated, in whole or in part, a Django model and then returned the records I populated.
Now I have a situation where I'd like to return some data that I don't wish to store in the Django model. Is this possible to do with Graphene?
Robert
Robert_LY answered his own question perfectly in the comments, I'd just like to expand his solution.
My database-less model WordForm is generated automatically, without storing it in a database. I define it as a Django model as follows:
from django.db import models
class WordForm(models.Model):
value = models.CharField(max_length=100)
attributes = models.CharField(max_length=100)
In the schema I define the node and query like this:
class WordFormNode(DjangoObjectType):
class Meta:
model = WordForm
interfaces = (relay.Node, )
class Query(AbstractType):
word_forms = List(WordFormNode,query=String(),some_id=String())
def resolve_word_forms(self, args, context, info):
query= args['query']
some_id = from_global_id(args['some_id'])[1]
word_forms = []
# some logic to make WordForm objects with
# WordForm(value=value,attributes=attributes),
# then append them to list word_forms
return word_forms
You can pass as many arguments as you like to the List and access them in resolve_word_forms.
When you map your Django model to a GraphQL, it create a new model with GraphQL object types from the introspection of the Django model..
And nothing prevent you to combine this model with with plain GraphQL objects types, or mapped from an other third party persistence model
I would like to filter Actions for particular queryset.
To this moment I was grabbing data by generating a model stream on desired model.
model_stream(FillingSystem)
I would like to extend this functionality and have something like this
model_stream(FillingSystem.objects.filter(client__slug='my-slug'))
or
model_stream(FillingSystem.objects.filter(client=Client.objects.get(slug='my-slug')))
this model looks like this:
class FillingSystem(models.Model):
client = models.ForeignKey('accounts.Client')
How do I filter a stream by related slug field?
It seems you can just pass your filters as **kwargs:
model_stream(FillingSystem, filling_system__client__slug='my-slug')
where target is a GenericForeignKey to your content (feel free to choose from the others).
You may have to declare a reverse relation to the Action model:
from django.contrib.contenttypes.fields import GenericRelation
from actstream.models import Action
class FillingSystem(models.Model):
client = models.ForeignKey('accounts.Client')
stream_actions = GenericRelation(
Action,
content_type_field='target_content_type'
object_id_field='target_object_id'
related_query_name='filling_system')
I want to define a selection field in python, i.e. field that is limited to a set of values. How can I do that in flask framework. I could not find anything on selection fields in the following sources:
Declaring Models
SQLAlchemy in Flask
I am using sqlalchemy for ORM.
I assume you mean a field in a form that has a limited set of options; to do this you can use WTForms and its extensions which allow you to create forms from models.
Once you have done that, you can then limit the choices for a field based on a model condition.
As you haven't posted your model, here is the example give you give you an idea on how this would work:
def enabled_categories():
return Category.query.filter_by(enabled=True)
class BlogPostEdit(Form):
title = TextField()
blog = QuerySelectField(get_label='title')
category = QuerySelectField(query_factory=enabled_categories,
allow_blank=True)
def edit_blog_post(request, id):
post = Post.query.get(id)
form = ArticleEdit(obj=post)
# Since we didn't provide a query_factory for the 'blog' field, we need
# to set a dynamic one in the view.
form.blog.query = Blog.query.filter(Blog.author == request.user) \
.order_by(Blog.name)