How to iterate through Reverse ManytoOne sets, Attribute Error - django

key = modelobj.__class__.__name__
keyval = modelobj.pk
sets = ['cat_set', 'dog_set']
for x in set:
test = eval(key).objects.get(pk=keyval).eval(x).values()
print(test)
The entries in the 'sets' list have a ManytoOne relationship (already defined in the model file) with the 'key'. When I run this script I get the error: "AttributeError: 'Activities' object has no attribute 'eval'" for the "eval(x)" part (the first eval(key) works fine).
For instance, if I change the line to the following code, it runs fine but I need to be less explicit:
test = eval(key).objects.get(pk=keyval).cat_set.values()

Use getattr and refer the model directly (why would you need to get the model name and run eval?):
model = modelobj.__class__
keyval = modelobj.pk
sets = ['cat_set', 'dog_set']
for x in set:
test = getattr(model.objects.get(pk=keyval), x).values()
print(test)

Related

Django form data loop

How can I loop through form data where the ending part could be 1,2,3,4 and so on, and store in the DB without hardcoding the DB like below so each description would be on its own line but one person could post description1-10 and the other 10-27 and so on
for example instead of say this
order.description_1 = request.POST.get('description1')
order.length_1 = request.POST.get('length1')
order.width_1 = request.POST.get('width1')
order.depth_1 = request.POST.get('depth1')
order.weight_1 = request.POST.get('weight1')
order.description_2 = request.POST.get('description2')
order.length_2 = request.POST.get('length2')
order.width_2 = request.POST.get('width2')
order.depth_2 = request.POST.get('depth2')
order.weight_2 = request.POST.get('weight2')
currently the form passes request.POST.get('description1') and with a limit of request.POST.get('description5') but would like each description on its own row and not be subject to a hardlimit and uses a bit of javascript to append the x value to the name. The postdata form is also hardcoded so not using forms.py
The request.POST is a python dictionary, so you can loop through it like this:
for key, value in request.POST.items():
print(key, value)
# set the property for order
# you can work on key and change it if need
setattr(order, key, value)
For a better implementation of this requirement, you can use django forms with ArrayField fields:
django simple array field
how-to-define-arrayfield-to-django-forms

django dynamic content in query

I am trying to "DRY" my code and would like to create a function to make my query dynamic.
The code that I currently use is :
rightone = []
for item in taglist: #taglist is a list of model instances, not relevant here
content = content.filter(tags__title=item.title) #tags here is a M2M key : my problem, content is a query
rightone.append(content)
tagproofquery = rightone[-1]
and I would like to convert it to:
def uniquetogether(queryset,data, model):
rightone = []
for item in queryset:
content = data.filter(tags__title=item.title) # <--- problem is here with tags
rightone.append(content)
tagproofquery = rightone[-1]
return tagproofquery
I have no idea how to replace my M2M "tags" as in tags__title=item.title with the "model" parameter of my function. I tried f strings but it failed miserably (of course).
Is there a way to do this? Many thanks

Unexpected behavior of ndb Structured Property

I am using ndb Structured property in my app. The models look like this:
Resource External Integration:
class ResourceExternalIntegration(ndb.Model):
integration_type = ndb.StringProperty()
external_resource_type = ndb.StringProperty()
external_resource_id = ndb.IntegerProperty()
external_group_id = ndb.IntegerProperty()
external_resource_name = ndb.StringProperty()
Resouce Model:
class Resource(ndb.Model):
owner = ndb.IntegerProperty()
name = ndb.StringProperty()
type = ndb.StringProperty()
external_integrations = ndb.StructuredProperty(ResourceExternalIntegration, repeated=True)
Note that i have structured property as repeated=True
Issue:
I have a function in Resource class which formats/serializes the data extracted from DB. It looks like this:
def serialize(self):
external_integrations_list = []
if self.external_integrations:
for external_integration in self.external_integrations:
external_integration_dict = dict()
external_integration_dict['integration_type'] = external_integration.integration_type,
external_integration_dict['external_resource_type'] = external_integration.external_resource_type,
external_integration_dict['external_resource_id'] = external_integration.external_resource_id
external_integration_dict['external_group_id'] = external_integration.external_group_id
external_integration_dict['external_resource_name'] = external_integration.external_resource_name
external_integrations_list.append(external_integration_dict)
resource_data.update(dict(
owner=self.owner,
name=self.name,
type=self.type,
external_integrations=external_integrations_list
))
return resource_data
Now, in the resource_data the attribute external_integrations should be an array and every element in it should also be an array i.e. external_resource_id, external_resource_type etc should also be an array. It is because of the fact that structured property was set as repeated=True. But, the resource_data does not contain this expected result. It looks like:
{'name': u'Scissors lift', 'type': u'Scissors', 'external_integrations': [{'external_resource_type': (u'FLEET',), 'integration_type': (u'ABC',), 'external_resource_id': 212017856321402L, 'external_resource_name': u"Test 1", 'external_group_id': 5000}],'owner': 5629490125014563L}
And, on browser it looks like this:
external_group_id: 5000
external_resource_id: 212017856321402
external_resource_name: "Test 1"
external_resource_type: ["FLEET"]
integration_type: ["ABC"]
i.e. the external_group_id, external_resource_id, external_resource_name does not appear as array, but they were expected as arrays.
I also have another model in which the structured property does not exists as repeated=True. It looks like:
External Integration
class ExternalIntegration(ndb.Model):
access_token = ndb.StringProperty()
group_ids = ndb.IntegerProperty(repeated=True)
Profile
class profile(ndb.Model):
name = ndb.StringProperty()
integration_info = ndb.StructuredProperty(ExternalIntegration)
Here, the serialize function of profile model show result as:
{'integration_info': {'group_ids': ([5000],), 'access_token': (u'blahblahblahblah',)}, ''name: 'Test'}
And, on browser the result looks like:
access_token: ["blahblahblahblah"]
group_ids: [[5000]]
I am unable to understand why access_token appears as an array and why groups_ids is an array of array.
Can anyone please help me understand such behavior of ndb structured property? Specifically the cases i explained above.
There are two questions here:
Regarding the profile model:
integration_info contains two elements defined in ExternalIntegration class. It is saved as a dictionary containing two elements: access_token and group_ids. group_ids is defined with repeated=True, which takes a list of values of the underlying type, which creates a list. To summarize:
access_token appears as a string.
group_ids appears as a list, because repeated is set to True.
Regarding the resource model:
external_integrations appear as a list, because you defined repeated=True.
There is only one element on the list because the whole dictionary was appended in a single operation, instead of element per element.
external_group_id, external_resource_id and external_resource_name don't appear as an array because they were not defined with repeated=True. The definition is applied one level above, to external_integrations, not to each of its contained strings.
Try to redefine the elements which should be repeated and the ones that shouldn't.

Training Doc2Vec on 20newsgroups dataset. Getting Exception AttributeError: 'str' object has no attribute 'words'

There were a similar question here Gensim Doc2Vec Exception AttributeError: 'str' object has no attribute 'words', but it didn't get any helpful answers.
I'm trying to train Doc2Vec on 20newsgroups corpora.
Here's how I build the vocab:
from sklearn.datasets import fetch_20newsgroups
def get_data(subset):
newsgroups_data = fetch_20newsgroups(subset=subset, remove=('headers', 'footers', 'quotes'))
docs = []
for news_no, news in enumerate(newsgroups_data.data):
tokens = gensim.utils.to_unicode(news).split()
if len(tokens) == 0:
continue
sentiment = newsgroups_data.target[news_no]
tags = ['SENT_'+ str(news_no), str(sentiment)]
docs.append(TaggedDocument(tokens, tags))
return docs
train_docs = get_data('train')
test_docs = get_data('test')
alldocs = train_docs + test_docs
model = Doc2Vec(dm=dm, size=size, window=window, alpha = alpha, negative=negative, sample=sample, min_count = min_count, workers=cores, iter=passes)
model.build_vocab(alldocs)
Then I train the model and save the result:
model.train(train_docs, total_examples = len(train_docs), epochs = model.iter)
model.train_words = False
model.train_labels = True
model.train(test_docs, total_examples = len(test_docs), epochs = model.iter)
model.save(output)
The problem appears when I try to load the model:
screen
I tried:
using LabeledSentence instead of TaggedDocument
yielding TaggedDocument instead of appending them to the list
setting min_count to 1 so no word would be ignored (just in case)
Also the problem occurs on python2 as well as python3.
Please, help me solve this.
You've hidden the most important information – the exact code that triggers the error, and the error text itself – in the offsite (imgur) 'screen' link. (That would be the ideal text to cut & paste into the question, rather than other steps that seem to run OK, without triggering the error.)
Looking at that screenshot, there's the line:
model = Doc2Vec("20ng_infer")
...which triggers the error.
Note that none of the arguments as documented for the Doc2Vec() initialization method are a plain string, like the "20ng_infer" argument in the above line – so that's unlikely to do anything useful.
If trying to load a model that was previously saved with model.save(), you should use Doc2Vec.load() – which will take a string describing a local file path from which to load the model. So try:
model = Doc2Vec.load("20ng_infer")
(Note also that larger models might be saved to multiple files, all starting with the string you supplied to save(), and these files must be kept/moved together to again re-load() them in the future.)

django Model form with initial and data values

I am trying to set my model form with data as well as initial_dict. They both are working fine indivisiually, but when i put both in the method call, Initial does not work.
here is the code.
state = Territory.objects.filter(abbreviation=request.GET.get('territory', ''))
if state:
initial_dict['state'] = state.get()
ctx['add_customer'] = AddCustomer(data=request.GET, initial=initial_dict)
But the state (Dropdown) does not get selected.
This works fine
ctx['add_customer'] = AddCustomer(initial=initial_dict)
Ideas?
This is actually solved my problem.
initial_dict = request.GET.dict()
state = Territory.objects.filter(abbreviation=initial_dict.get('state', ''))
if state:
initial_dict['state'] = state.get()
ctx['add_customer'] = AddCustomer(initial=initial_dict)
Converted data to Python Dict & use only Initial.
I am still not sure why that problem was occurring.