how to handle django many to many mapper object [duplicate] - python

This question already has an answer here:
Django: show list of many to many items in the admin interface
(1 answer)
Closed 9 years ago.
i have model :
class tags(models.Model):
""" This is the tag model """
tag = models.CharField(max_length=15) # Tag name
tagDescription = models.TextField() # Tag Description
tagSlug = models.CharField(max_length=400) # Extra info can be added to the existing tag using this field
createdAt = models.DateTimeField(auto_now_add=True)
updatedAt = models.DateTimeField(auto_now=True)
def __unicode__(self):
return unicode(self.tag)
class stores(models.Model):
""" This is the store model """
storeName = models.CharField(max_length=15) # Store Name
storeDescription = models.TextField() # Store Description
storeURL = models.URLField() # Store URL
storePopularityNumber = models.IntegerField(max_length=1) # Store Popularity Number
storeImage = models.ImageField(upload_to=storeImageDir) # Store Image
storeSlug = models.CharField(max_length=400) # This is the text you see in the URL
createdAt = models.DateTimeField(auto_now_add=True) # Time at which store is created
updatedAt = models.DateTimeField(auto_now=True) # Time at which store is updated
storeTags = models.ManyToManyField(tags) # All the tags associated with the store
def __unicode__(self):
return unicode(self.storeName)
def StoreTags(self):
return unicode(self.storeTags.all())
It is displaying [] under StoreTags
this is storesAdmin class:
class storesAdmin(admin.ModelAdmin):
list_display = ('storeName','storeDescription','storeURL',
'storePopularityNumber','storeImage',
'storeSlug','createdAt','createdAt','StoreTags'
)
Why it is displaying like that i even tried to convert it into unicode but it not working..

Avoid using CamelCase in Model Fields. Django Codigo Style - Model Field
"Field names should be all lowercase, using underscores instead of camelCase."
Avoid using CamelCase in functions and methods.
"Use underscores, not camelCase, for variable, function and method names (i.e. poll.get_unique_voters(), not poll.getUniqueVoters)."
Try choosing another name for storetags method. Maybe it clashes with storetags field name.django hash object

Try with code:
models
class Tags(models.Model):
#...
def __unicode__(self):
return '%s' % self.tag
class Stores(models.Model):
#...
def __unicode__(self):
return '%s' % self.storeTags.tag
admin, list_display is not supported to ManyToMany, i'm remove storetags
class storesAdmin(admin.ModelAdmin):
list_display = ('storename','storedescription','storeurl',
'storepopularitynumber','storeimage',
'storeslug','createdat','createdat'
)
Tell me if it works correctly.

Related

Django Filter name "todo__test" is not defined

I'm trying to filter my Todos by the test_id pulled from the URL. It pulls the id from the URL but it cant seem to filter with todo__test. I have also tried "test", "Todo.test.test_id", "Todo.test". I guess I'm confused about what variable I need to filter and the Django restframework documentation doesn't explicitly show what variable to use. Their example uses "purchaser__username" which I don't understand where it comes from. https://www.django-rest-framework.org/api-guide/filtering/
class TodoList(generics.ListAPIView):
queryset = Todo.objects.all()
serializer_class = TodoSerializer
def get_queryset(self):
test_id = self.kwargs['test_id']
return Todo.objects.filter(todo__test == test_id)
class Todo(models.Model):
test = models.ForeignKey(Test, on_delete=models.CASCADE)
content = models.TextField(blank=True)
order = models.IntegerField()
def __str__(self):
return self.content + ' - ' + self.test.test_name
class Meta:
ordering = ['test_id']
i guess it will be like this. you passed incorrect foreign key field name.
Todo.objects.filter(test_id='whatever_value')

Django model function implementation to auto initialize a particular field's value

I need to write a Django model function to calculate the value of an existing field.
my models.py:
class questionNumeric(models.Model):
question = models.TextField()
marks = models.IntegerField()
correctAns = models.FloatField()
class questionTureFalse(models.Model):
question = models.TextField()
marks = models.IntegerField()
correctAns = models.BooleanField()
class questionSet(models.Model):
examName = models.CharField(max_length=200)
questionNumeric = models.ManyToManyField(questionNumeric)
questionTureFalse = models.ManyToManyField(questionTureFalse)
totalMarks = models.IntegerField(default=0)
As you can see here, each questionNumeric or questionTureFalse object has specific marks. Now I want to set my questionSet object's totalMarks field with- the summation of marks carried by all questionNumeric or questionTureFalse under this questionSet object.
How can I write a Django Model function under questionSet to auto initialize totalMarks?
You can declare a function in questionSet and return count of relations. For example sth like:
class QuestionSet(models.Model):
...
def get_question_numeric_count(self):
return self.questionNumeric.count()

django views, getting request and using it as a parameter

I'm very confused about this right now,
so I know when there's a simple code like the below
def text_detail(request ,course_pk, step_pk):
step = get_object_or_404(Text, course_id = course_pk, pk=step_pk)
course_pk and step_pk from the url, and those requests are set equal to course_id and pk here. but what I don't understand is what is course_id and pk here? I mean, course_id is from Course model which is foreignkey to step. so it's self.Course.id so it's course_id. But then, how about the next one pk? shouldn't it be step_id = step_pk? when it's just pk how does django know which pk it is?
Sorry if the question is very confusing, I'm very confused right now.
Edit
class Step(models.Model):
title = models.CharField(max_length=200)
description = models.CharField()
order = models.IntegerField(default=0)
course = models.ForeignKey(Course)
class Meta:
abstract = True
ordering = ['order',]
def __str__(self):
self.title
class Text(Step):
content = models.TextField(blank=True, default="")
Actually the get_or_404() method doing a similar/exact job as below,
try:
return Text.object.get(pk=step_pk,course_id = course_pk)
except Text.DoesNotExist:
raise Http404
You can read the source code of the same here
What is course_id and pk ?
Both are attributes of your Text model, as the name indicates pk is your Primary Key of Text model and course_id is the id/pk of course field which is a FK.
EDIT
Text is inherited from Step model so, it will show properties of usual python class.Hence, the Text model be like this internally (not-exact)
class Text(models.Model):
content = models.TextField(blank=True, default="")
title = models.CharField(max_length=200)
description = models.CharField()
order = models.IntegerField(default=0)
course = models.ForeignKey(Course)
class Meta:
ordering = ['order', ]
def __str__(self):
return self.title
Example
text = Text.objects.get(id=1) # text instance with id=1
text.course_id # will hold the id of "course" instance which is related to the particular "text" instance
URL assignment and all those stuffs are entirely depends on your choice and logic. So If you need to get a Text instance in your view, do as below,
text = get_object_or_404(Text, pk = pk_of_TEXT_instance)

Django Python - How to add foreign key to table displayed in admin page

So I got 4 tables in a MySQL database.
The database is managed with Django under an app I created with Django.
Here are 2 of the 4 classes in the file models.py corresponding to the database tables:
from __future__ import unicode_literals
from django.db import models
class Pdb(models.Model):
id_pdb_chain = models.CharField(db_column='id_PDB_chain', primary_key=True, max_length=5) # Field name made lowercase.
id_pdb = models.CharField(db_column='id_PDB', max_length=4) # Field name made lowercase.
chaine = models.CharField(max_length=10)
header = models.CharField(max_length=255)
sequence_proteine = models.TextField(db_column='sequence_Proteine') # Field name made lowercase.
start_seq = models.IntegerField()
taille_proteine = models.IntegerField(db_column='taille_Proteine') # Field name made lowercase.
resolution_pdb = models.FloatField(db_column='resolution_PDB') # Field name made lowercase.
meth_res = models.ForeignKey('MethodesRes', models.DO_NOTHING, db_column='meth_Res') # Field name made lowercase.
def __unicode__(self):
return self.id_pdb
class Meta:
managed = False
db_table = 'PDB'
class StructSec(models.Model):
id_struct_sec = models.AutoField(primary_key=True)
start_pred = models.IntegerField()
structure_predite = models.TextField(db_column='structure_Predite') # Field name made lowercase.
nombre_ppii = models.IntegerField(db_column='nombre_PPII') # Field name made lowercase.
pourcentage_ppii = models.FloatField(db_column='pourcentage_PPII') # Field name made lowercase.
angle_phi = models.TextField()
angle_psi = models.TextField()
id_pdb_chain = models.ForeignKey(Pdb, models.DO_NOTHING, db_column='id_PDB_chain') # Field name made lowercase.
nom_analyse = models.ForeignKey(MethodesAnalyse, models.DO_NOTHING, db_column='nom_Analyse') # Field name made lowercase.
def __unicode__(self):
return self.structure_predite
class Meta:
managed = False
db_table = 'struct_sec'
As you can see I already found a way to display a field for each table in the admin page with this part in each table:
def __unicode__(self):
return self.structure_predite
But when I want to replace "structure_predite" this by the primary key in the "StructSec" class like this:
def __unicode__(self):
return self.id_struct_sec
Django return this error:
TypeError: coercing to Unicode: need string or buffer, long found
I also have to mention that I have made few modifications in the "admin.py" file here it is:
from django.contrib import admin
from .models import Pdb, MethodesAnalyse, MethodesRes, StructSec
class PdbInline(admin.TabularInline):
model = Pdb
class PdbAdmin(admin.ModelAdmin):
list_display = ('id_pdb','header','chaine','taille_proteine','meth_res')
list_filter = ['chaine','meth_res']
search_fields = ['id_pdb_chain','header']
class MethodesAnalyseInline(admin.TabularInline):
model = MethodesAnalyse
class MethodesAnalyseAdmin(admin.ModelAdmin):
list_display = ('nom_analyse')
class MethodesResInline(admin.TabularInline):
model = MethodesRes
class MethodesResAdmin(admin.ModelAdmin):
list_display = ('meth_res')
class StructSecInline(admin.TabularInline):
model = MethodesRes
class StructSecAdmin(admin.ModelAdmin):
list_display = ('id_struct_sec','nombre_PPII','pourcentage_PPII','id_PDB','nom_Analyse')
search_fields = ['nombre_ppii','pourcentage_ppii']
admin.site.register(Pdb,PdbAdmin)
admin.site.register(MethodesAnalyse)
admin.site.register(MethodesRes)
admin.site.register(StructSec)
Knowing this, my question is simple:
How to display the autoincremented IDs (Primary Key) from the class StructSec in the corresponding admin table without errors?
I think the error is raising due to None value. Python cannot convert None.
Replace your unicode definition to 'str' as:
def __str__(self):
return self.id_struct_sec
Sijan answer is correct, I will just add that, to make links work, you may also have to do this:
def __str__(self):
return str(self.id_struct_sec)
Without the "str()" in the return, links don't work and return errors when clicked.

Python convert string to class

I want to do a query on the django User table like this:
u = User.objects.filter(member__in = member_list)
where:
class Member(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
dob = models.DateField('Date of Birth', blank=True, null=True)
and member_list is a list of eligible members.
The query works fine but the problem is I do not actually know the model member is called member. It could be called anything.
I store the name of the model I want in a model called Category. I have a link to the name of the model through content_type.Category is defined as:
class Category(models.Model):
name = models.CharField('Category', max_length=30)
content_type = models.ForeignKey(ContentType)
filter_condition = JSONField(default="{}", help_text=_(u"Django ORM compatible lookup kwargs which are used to get the list of objects."))
user_link = models.CharField(_(u"Link to User table"), max_length=64, help_text=_(u"Name of the model field which links to the User table. 'No-link' means this is the User table."), default="No-link")
def clean (self):
if self.user_link == "No-link":
if self.content_type.app_label == "auth" and self.content_type.model == "user":
pass
else:
raise ValidationError(
_("Must specify the field that links to the user table.")
)
else:
if not hasattr(apps.get_model(self.content_type.app_label, self.content_type.model), self.user_link):
raise ValidationError(
_("Must specify the field that links to the user table.")
)
def __unicode__(self):
return self.name
def _get_user_filter (self):
return str(self.content_type.app_label)+'.'+str(self.content_type.model)+'.'+str(self.user_link)+'__in'
def _get_filter(self):
# simplejson likes to put unicode objects as dictionary keys
# but keyword arguments must be str type
fc = {}
for k,v in self.filter_condition.iteritems():
fc.update({str(k): v})
return fc
def object_list(self):
return self.content_type.model_class()._default_manager.filter(**self._get_filter())
def object_count(self):
return self.object_list().count()
class Meta:
verbose_name = _("Category")
verbose_name_plural = _("Categories")
ordering = ('name',)
So I can retrieve the name of the model that links to User but I then need to convert it into a class which I can include in a query.
I can create an object x = category.content_type.model_class() which gives me <class 'cltc.models.Member'> but when I them perform a query s = User.objects.filter(x = c.category.object_list()) I get the error Cannot resolve keyword 'x' into field.
Any thoughts most welcome.
The left hand side of the filter argument is a keyword, not a python object, so x is treated as 'x', and Django expects a field called x.
To get around this, you can ensure that x is a string, and then use the python **kwarg syntax:
s = User.objects.filter(**{x: c.category.object_list()})
Thanks to https://stackoverflow.com/a/4720109/823020 for this.

Categories