Djongo - Cannot put my own models in documents - django

I have the following Python code that I am trying to migrate from mongonaut to the new way of interfacing Django with MongoDB, the djongo package:
# CharField for English and Japanese text
class LocalizedCharField(models.Model):
EN = models.CharField()
JP = models.CharField()
class Meta:
abstract = False
# Details for a character
class CharacterInfo(models.Model):
charName = models.CharField(max_length=128, blank=False, null=False)
displayName = models.EmbeddedField(model_container=LocalizedCharField)
nationality = models.EmbeddedField(model_container=LocalizedCharField)
game = models.EmbeddedField(model_container=LocalizedCharField)
system = models.EmbeddedField(model_container=LocalizedCharField)
voice = models.EmbeddedField(model_container=LocalizedCharField)
graphic = models.EmbeddedField(model_container=LocalizedCharField)
introduction = models.EmbeddedField(model_container=LocalizedCharField)
defaultPalIndices = models.CharField(max_length=128)
groove = models.JSONField(blank=True, null=True)
config = models.JSONField()
moves = models.JSONField()
charConfig = models.JSONField()
def __unicode__(self):
return self.charName
class Meta(object):
verbose_name = "Character"
verbose_name_plural = "Characters"
# Main page post
class Post(models.Model):
title = models.EmbeddedField(model_container=LocalizedCharField)
date = models.DateTimeField(default=datetime.datetime.now)
content = models.EmbeddedField(model_container=LocalizedCharField)
def __unicode__(self):
return self.title["EN"]
However, I get the following error when I try to debug my server:
['Field "lawn.LocalizedCharField.id" of model container:"<class \'lawn.models.LocalizedCharField\'>" cannot be of type "<class \'django.db.models.fields.AutoField\'>"']
And it points to the line where displayName is as the culprit, meaning I for some reason can't embed my own field types in other models? What do I have to do to make this work? As said before, up until this point, I was using an outdated custom build of Mongonaut where this worked fine, so I'm unsure what djongo wants.

Related

Django ModelForm foreign key values are not displayed

Am new to Django, and I am trying to create a form using model form. The form has a foreign key value (connection_type below in forms.py) and it's not displaying the values it is referring to.
For the image below, the columns,
Connection name: displayed
Connection type: text box has not appeared
Endpoint: displayed
Image from the browser
forms.py
class ConnectionForm(forms.ModelForm):
connection_type = forms.ModelChoiceField(queryset=ConnectionTypes.objects.all(), to_field_name='connection_type_id')
class Meta:
model = ConnectionDetails
exclude = ['connection_id','last_update_date']
Models.py
class ConnectionDetails(models.Model):
connection_id = models.IntegerField(primary_key=True,default=re_sequence('connection_seq'))
connection_name = models.CharField(max_length=200)
connection_type = models.IntegerField()
endpoint = models.CharField(max_length=100)
port = models.IntegerField()
login_id = models.CharField(max_length=100)
login_password = fields.CharPGPPublicKeyField(max_length=100)
connection_string_1 = fields.CharPGPPublicKeyField(max_length=100)
connection_string_2 = fields.CharPGPPublicKeyField(max_length=100)
connection_string_3 = fields.CharPGPPublicKeyField(max_length=100)
aws_region = models.CharField(max_length=20)
owner_id = models.IntegerField()
last_update_date = models.DateTimeField(default=dbcurr_ts)
working_schema = models.CharField(max_length=100)
service = models.CharField(max_length=100)
def generate_enc(mystrenc):
return 'pass'
class Meta:
managed = False
db_table = 'connection_details'
verbose_name = 'connection_details'
verbose_name_plural = 'connection_details'
class ConnectionTypes(models.Model):
connection_type_id = models.IntegerField(primary_key=True,default=re_sequence('connection_type_seq'))
connection_type_name = models.CharField(max_length=100)
connection_type_desc = models.CharField(max_length=300)
connection_type_category = models.CharField(max_length=100)
last_update_date = models.DateTimeField(default=dbcurr_ts)
class Meta:
managed = False
db_table ='connection_types'
verbose_name = 'connection_types'
verbose_name_plural = 'connection_types'
Can you please let me know what is mistake am making?
One issue is that the model field for connecton_types takes an IntegerField. Yet, you are giving it a ModelChoiceField in the form. I think if you set connection_type as models.ForeignKey(ConnectionType, on_delete=models.CASCADE) or something similar in your models.py, it should work better. This way the ConnectionType is directly linked to whatever ConnectionDetails you have.

Advice Needed for the Structure of Many-To-Many Fields in Django

I am building a REST-API that will be consumed by an Angular application - this is for my guitar company’s website. There is an Artist Profile page that display an artist’s name, a short bio and a list of the projects(bands) they’re associated with and the date-ranges they were active with them. Here is where things get complicated.
Any given project can be associated with more than one artist - i.e. I could have two guitar players from the same band. I was able to solve that association by creating a many-to-many field and it worked great…until I realized that I have artists who have been in the same band at different times.
I have tried many approaches so far. I wish I could list them, but I kinda lost track. But, the code below is the where I am at right now. I can indeed associate a band with multiple artists, but I can’t associate different date ranges to different artists in the same bands. Any guidance is much appreciated.
class projectDate(models.Model):
begin = models.DateField()
end = models.DateField()
def __str__(self):
string_date_range = self.begin.strftime("%d/%m/%y") + "-" + self.end.strftime("%d/%m/%y")
return string_date_range
class artistProfiles(models.Model):
artist_name = models.CharField(max_length=20)
artist_image = models.URLField()
description = models.TextField(max_length=500)
band_website = models.URLField()
def __str__(self):
return self.artist_name
class artistProjects(models.Model):
project_name = models.CharField(max_length=20)
dates = models.ManyToManyField(projectDate, related_name='date_span')
artists = models.ManyToManyField(artistProfiles, related_name='projects')
def __str__(self):
return self.project_name
class artistSocialMedia(models.Model):
facebook = models.URLField()
twitter = models.URLField()
instagram = models.URLField()
artist = models.ForeignKey(artistProfiles, related_name='social_media', on_delete=models.CASCADE)
def __str__(self):
return self.artist.artist_name
artistProjects and projectDate should not be a many-to-many relationship, since a projectDate is specific to a project and unlikely to be shared by many. You can instead make artistProjects a foreign key in projectDate so that a artistProjects can have many projectDates but not vice versa:
class projectDate(models.Model):
begin = models.DateField()
end = models.DateField()
project = models.ForeignKey(artistProjects, related_name='dates')
Note that your artistProjects represents just one project, so you should avoid giving it a plural name. Naming it artistProject will make your code more readable.
Not sure whether i can solve your problems or not. I am going to describe it in simple way so you can just adjust it with your models.
These is my advice. Hope it solve your problems.
Artist Profile
id (PK)
artist_name
artist_image
description
band_website
Artist Social Media
id (PK)
artist_profile_id (FK)(Artist Profile)
facebook
twitter
instagram
Artist Project
id (PK)
artist_band_project_id (FK)(Artis Band Project)
Artist Band Project
id (PK)
begin
end
Artist Band Project Member
id (PK)
artis_band_project_id (FK)(Artist Band Project)
artis_profile_id (FK)(Artist Profile)
Regards,
Meikelwis Wijaya
#blhsing Ended up being the closest of all answers, but it took a little more massaging to get the relationships and JSON structure I was looking for.
Here is what worked for the models:
from django.db import models
class artistProfile(models.Model):
artist_name = models.CharField(max_length=20)
artist_image = models.URLField()
description = models.TextField(max_length=500)
band_website = models.URLField()
def __str__(self):
return self.artist_name
class artistProject(models.Model):
project_name = models.CharField(max_length=20)
def __str__(self):
return self.project_name
class projectTenure(models.Model):
begin = models.DateField()
# blank and null are allowed here in case an artists is still with a given project
end = models.DateField(blank=True, null=True)
project = models.ForeignKey(artistProject, on_delete=models.CASCADE)
artist = models.ForeignKey(artistProfile, on_delete=models.CASCADE,
related_name='projects')
def __str__(self):
# TODO: find a way to return the related project and artist names
string_date_range = self.begin.strftime("%d/%m/%y") + "-"
return string_date_range
class artistSocialMedia(models.Model):
facebook = models.URLField()
twitter = models.URLField()
instagram = models.URLField()
artist = models.ForeignKey(artistProfile, related_name='social_media',
on_delete=models.CASCADE)
def __str__(self):
return self.artist.artist_name
And here is how I serialized it:
from rest_framework import serializers
from .models import (artistProfile, artistProject, projectTenure, artistSocialMedia)
class artistSocialMediaSerializer(serializers.ModelSerializer):
class Meta:
model = artistSocialMedia
fields = ('facebook', 'twitter', 'instagram')
class artistProjectSerializer(serializers.ModelSerializer):
class Meta:
model = artistProject
fields = ('project_name',)
class projectTenureSerializer(serializers.ModelSerializer):
project_name = serializers.CharField(source='project.project_name')
class Meta:
model = projectTenure
fields = ('project_name', 'begin', 'end')
class artistProfileSerializer(serializers.ModelSerializer):
projects = projectTenureSerializer(many=True, read_only=True)
social_media = artistSocialMediaSerializer(many=True, read_only=True)
class Meta:
model = artistProfile
fields = ('artist_name', 'artist_image', 'description',
'band_website', 'projects', 'social_media')

Django inline model formset with 2 models

First of all, please forgive for my newbie questions. I did copy most of the code, and try to understand from Django documents.
Code as below:
models.py
class Order(models.Model):
ORDER_CHOICES = (
('import', 'IMPORT'),
('export', 'EXPORT')
)
storage = models.ForeignKey(Storage, on_delete=models.PROTECT)
order_type = models.CharField(max_length=6, choices=ORDER_CHOICES)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now_add=True)
class Item(models.Model):
def random_barcode():
return str(random.randint(10000000, 99999999))
type = models.ForeignKey(Type, on_delete=models.CASCADE)
order = models.ForeignKey(Order, on_delete=models.CASCADE, null=True)
brand = models.ForeignKey(Brand, on_delete=models.CASCADE)
item_name = models.CharField(max_length=50, help_text='Name of goods, max 50 characters')
barcode = models.CharField(max_length=8, default=random_barcode, unique=True)
production_date = models.DateField()
expired_date = models.DateField()
def __str__(self):
return self.item_type
forms.py
class ItemForm(ModelForm):
class Meta:
model = Item
exclude = ['order',]
fields = ['type', 'brand', 'item_name', 'production_date', 'expired_date']
ItemFormSet = inlineformset_factory(Order, Item, form=ItemForm, extra=1)
views.py
class CreatePO(CreateView):
model = Order
context_object_name = 'orders'
template_name = 'storages/create_po.html'
fields = ['order_type', 'storage',]
*#dun't know how to write below code....*
1st question: how to use inline formset to write the CreatePO view?
2nd question: I need my create PO template as below picture, how to add a "Quantity" field?
This kind of template need Javascript, right? Any alternative solution? I have no knowledge with javascript.
First of all, move the def random_barcode(): before def __str__(self): it looks so ugly formated code.
Then let's have a look in your pic, if you haven't proper experience with Javascript you can use Admin Views from Django, it's much more simple and supported by Django 2.1. Read more if you would like to give permission to everyone in a admin-views page https://docs.djangoproject.com/el/2.1/releases/2.1/#model-view-permission
So quantity will be just added inside Item class
quantity = models.PositiveSmallIntegerField(default=1)
Also for your form, in my opinion, you need modelform_factory, so I suggest to read this one https://docs.djangoproject.com/en/2.1/topics/forms/modelforms/#modelform-factory-function

Django cms - plugin manyToMany variable always empty

I wrote a simple plugin which display contact people, but I need to exclude some contact on certain pages. So I added a related model to my plugin which use an "structure_to_exclude" ManyToMany relationship. My issue, when I get this variable it's allways empty.
The cms_plugins.py
class VMContactContactPlugin(CMSPluginBase):
module = 'VM Contact Plugin'
render_template = 'vm_contact/calendars/contacts_list.html'
model = VMContactCalendarPluginModel
name = _('VM Contact plugin')
def render(self, context, instance, placeholder):
print 'Instance : {0}'.format(instance)
inst = instance.structure_to_exclude.all()
print 'Instance.all() result : {0}'.format(inst)
structures = Structure.objects.exclude(contact=None).exclude(pk__in=instance.structure_to_exclude.all().values_list('id',flat=True))
context.update({
'structures': structures,
})
return context
plugin_pool.register_plugin(VMContactContactPlugin)
The related model
class VMContactCalendarPluginModel(CMSPlugin):
structure_to_exclude = models.ManyToManyField(
Structure,
verbose_name=_(u'Structures à exclure'),
)
The Structure Models (Polymorphic !!)
class Structure(PolymorphicModel):
contact = models.ForeignKey(Contact, blank=True, null=True)
members = models.ManyToManyField(Contact, blank=True, null=True, related_name='%(class)s_members')
title = models.CharField(max_length=50, default='Castor')
description = models.CharField(max_length=254, blank=True)
categories = CategoryManyToManyField('aldryn_categories.Category',
verbose_name=_('categories'),
blank=True)
calendars = models.ManyToManyField(Calendar, blank=True)
has_pages = models.BooleanField(default=True)
avatar = FilerFileField(null=True, blank=True,
on_delete=models.SET_NULL)
classcss = models.CharField(max_length=1, choices=CSS_CLASS, default='5')
order = models.PositiveSmallIntegerField(default=0)
class Meta:
ordering = ['order']
Print results :
Instance : 93
Instance.all() result : []
Any idea ? I tried to retrieve the plugin instance with the ID (93) to be sure that was not an issue with instance var but it doesn't change anything...
Regards, robin
For every plugin you create, there's two versions once you publish.
The public and the draft versions. So its perfectly fine for the ids to change.
Because relationships vary from project to project, anytime your plugin has relationships, you need to explicitly tell the cms how to "copy over" these relationships when publishing the page.
Please adapt your plugin model to have the following method:
def copy_relations(self, oldinstance):
self.structure_to_exclude = oldinstance.structure_to_exclude.all()
You can read more about plugin relations in our docs.

Integrating Photologue

I want to integrate photologue with my Django app and use it to display photos in a vehicle inventory...kinda like what is offered by Boost Motor Group Inc. I've already integrated the app so the next step which I'm trying to figure out is how to hook it up into my vehicle model and also how to display the photos. My vehicle model looks like this BTW
class Vehicle(models.Model):
stock_number = models.CharField(max_length=6, blank=False)
vin = models.CharField(max_length=17, blank=False)
common_vehicle = models.ForeignKey(CommonVehicle)
exterior_colour = models.ForeignKey(ExteriorColour)
interior_colour = models.ForeignKey(InteriorColour)
interior_type = models.ForeignKey(InteriorType)
odometer_unit = models.ForeignKey(OdometerUnit)
status = models.ForeignKey(Status)
odometer_reading = models.PositiveIntegerField()
selling_price = models.PositiveIntegerField()
purchase_date = models.DateField()
sales_description = models.CharField(max_length=60, blank=False)
feature_sets = models.ManyToManyField(FeatureSet, blank=True)
features = models.ManyToManyField(Feature, blank=True)
def __unicode__(self):
return self.stock_number
For your purposes I would recommend you check out django-imagekit (I wrote both imagekit and photologue). It was designed to be integrated into other applications as opposed to being a stand-alone application itself. After that, as Dominic said, we'll need to know more about your requirements.
I use ImageKit (great!)
model.py
from imagekit.models import ImageModel
class Photo(ImageModel):
name = models.CharField(max_length=100)
original_image = models.ImageField(upload_to='photos')
num_views = models.PositiveIntegerField(editable=False, default=0)
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
content_object = generic.GenericForeignKey('content_type', 'object_id')
class IKOptions:
# This inner class is where we define the ImageKit options for the model
spec_module = 'cms.specs'
cache_dir = 'photos'
image_field = 'original_image'
save_count_as = 'num_views'
class Vehicle(models.Model):
images = generic.GenericRelation('Photo', blank = True, null = True)
specs.py
from imagekit.specs import ImageSpec
from imagekit import processors
from imagekit.lib import *
# first we define our thumbnail resize processor
class ResizeThumb(processors.Resize):
width = 100
height = 75
crop = True
# now lets create an adjustment processor to enhance the image at small sizes
class EnchanceThumb(processors.Adjustment):
contrast = 1.2
sharpness = 1.1
# now we can define our thumbnail spec
class Thumbnail(ImageSpec):
processors = [ResizeThumb, EnchanceThumb]
in your template you will access this thumbnails like this:
{% for p in vehicle.images.all %}
{{ p.get_thumbnail.url }}
{% endfor %}
admin.py could look like this:
class ImagesInline(generic.GenericTabularInline):
model = Photo
max_num =4
class VehicleAdmin(admin.ModelAdmin):
inlines = [ImagesInline]
All about ImageKit
add the file specs.py to your app and tell ImageKit of it like this
class IKOptions:
# This inner class is where we define the ImageKit options for the model
spec_module = 'cms.specs # ur_app.specs
add a field to your Photo-Model to save what kind of view/ content it shows. i.e. ChoiceField
In view/template you can filter for it