I have an object:
POP_CULTURE_TYPES = (
('SG','Song'),
('MV', 'Movie'),
('GM', 'Game'),
('TV', 'TV'),
)
class Pop_Culture(models.Model):
name = models.CharField(max_length=30, unique=True)
type = models.CharField(max_length=2, choices = POP_CULTURE_TYPES, blank=True, null=True)
Then I have a function:
def choice_list(request, modelname, field_name):
mdlnm = get.model('mdb', modelname.lower())
mdlnm = mdlnm.objects.values_list(field_name, flat=True).distinct().order_by(field_name)
return render_to_response("choice_list.html", {
'model' : modelname,
'field' : field_name,
'field_list' : mdlnm })
This gives me a distinct list of all the "type" entries in the database in the "field_list" variable passed in render_to_response. But I don't want a list that shows:
SG
MV
I want a list that shows:
Song
Movie
I can do this on an individual object basis if I was in the template
object.get_type_display
But how do I get a list of all of the unique "type" entries in the database as their full names for output into a template?
I hope this question was clearly described. . .
How about something like this at the end of your choice_list()?
def choice_list(request, modelname, field_name):
# ...
pct = dict(POP_CULTURE_TYPES)
return [pct[key] for key in mdlnm]
Or in one line w/o the dict() call:
return [pct[1] for pct in POP_CULTURE_TYPES if pct in mdlnm]
Not pretty but it will work until to run across something better.
You could use:
OBJECT.get_FIELD_display()
Example:
content = Pop_Culture.objects.get(...)
ctype = content.get_type_display()
There is no need for workarounds :)
Related
I am trying to insert data but am getting ValueError while inserting due to ForeignKey.
class Test(models.Model):
test_name = models.CharField(max_length=20, unique=True)
test_code = models.SlugField(max_length=10, name='Code',unique=True)
referance_value = models.CharField(name='Referance', max_length=20)
def __str__(self):
return self.test_name
class TestTaken(models.Model):
app_code = models.CharField(max_length=20,unique=True)
user_name = models.CharField(name='Username',max_length=20)
test_names = models.ForeignKey(Test, on_delete=models.CASCADE)
result_value = models.CharField(name='ResultValue',max_length=20)
def __str__(self):
return self.app_code
Below is my View.py
def alltestdata(request):
if request.method == 'POST':
app_code = request.POST.getlist('app_code')
test_name = request.POST.getlist('name')
test_list = request.POST.getlist('test_list')
for i, j , k in zip(app_code, test_name, test_list):
book = TestTaken(app_code=i, ResultValue=j, test_names=k, Username=request.user.username)
book.save()
return redirect('lab:Dashboard')
Am geting following error
ValueError: Cannot assign "'eeeee'": "TestTaken.test_names" must be a "Test" instance.
The error holds the answer to your question: test_names is a ForeignKey, not a string. To set it from a name, you first need to find the key into the Test table. This can be done with a get or get_or_create, depending on how you want to handle missing tests.
NOTE: test_names is not a very good name for that ForeignKey field and probably caused this confusion. It shouldn't be plural, and points to a Test object, not just a name. You probably want something more like test
There is some additional confusion in your code. First, you seem to have swapped values in your inner iteration (j gets its value from test_name and is then applied to ResultValue, while k comes from test_list but goes to test_names instead). You can avoid confusion like this by using more explicit variable names. The second source of confusion is in the variable names app_code, test_name, and test_list, all of which seem to be lists, but only one of them has a name that seems to reflect this.
Combining these points into code, try something like the following. Note that I have changed some of the names of variables to reflect what I think you intended, and I have used a simple get_or_create, while you might want something else. Adjust to suit your needs:
# in your model
class Test(models.Model):
test_name = models.CharField(max_length=20, unique=True)
test_code = models.SlugField(max_length=10, name='Code',unique=True)
referance_value = models.CharField(name='Referance', max_length=20)
def __str__(self):
return self.test_name
class TestTaken(models.Model):
app_code = models.CharField(max_length=20,unique=True)
user_name = models.CharField(name='Username',max_length=20)
test = models.ForeignKey(Test, on_delete=models.CASCADE)
result_value = models.CharField(name='ResultValue',max_length=20)
def __str__(self):
return self.app_code
# in View.py
def alltestdata(request):
if request.method == 'POST':
app_codes = request.POST.getlist('app_code')
test_names = request.POST.getlist('name')
scores = request.POST.getlist('test_list')
for code, test_name, score in zip(app_codes, test_names, scores):
test_obj, _ = Test.objects.get_or_create(test_name=test_name)
book = TestTaken(app_code=code, ResultValue=score, test=test_obj, Username=request.user.username)
book.save()
return redirect('lab:Dashboard')
I have a class student_student which have a one2many fieldresult_ids defined like the following:
result_ids = fields.One2many("schoolresults.detail", "student_id", "School Results", default="_get_subjects")
and
def _get_subjects(self):
cr = self.pool.cursor()
self.env
return self.pool.get('schoolresults.subject').search(cr, self.env.uid, [])
in the other side I have a class schoolresults_subject:
class schoolresults_subject(models.Model):
_name = "schoolresults.subject"
_description = "Student's subjects."
name = fields.Char("Subject")
class schoolresults_detail(models.Model):
_name = "schoolresults.detail"
_description = "Student's results."
student_id = fields.Many2one("student.student", "Student", ondelete="cascade")
subject_id = fields.Many2one("schoolresults.subject", "Subject")
result = fields.Float("Result", compute='_compute_value', store=True)
What I'm trying to do is to fill the result_ids with a subjects list from the last class, whenever the user trying to create a new student profile, using the the default parameter in the one2many field.
But whenever I try to create a student profile I get this error Wrong values for student.student.result_ids.
Please is there anyway to achieve that?
PS. I'm using Odoo 9
I don't get your requirements here fully, but try something like the following:
def _get_subjects(self):
subjects = self.env['schoolresults.subject'].search([])
details = self.env['schoolresults.detail']
for subject in subjects:
details |= details.new({'subject_id': subject.id})
return details
But explaining the error message: you're returning a RecordSet of schoolresults.subject but your field result_ids has the comodel schoolresults.detail. That's just wrong ;-)
I could do this by overriding the default_get method:
def default_get(self, fields):
res = super(student_student, self).default_get(fields)
srd = self.env['schoolresults.detail']
ids=[]
school_result={'subject_id':1,'result':0} #dict for fields and their values
sr = srd.create(school_result)
ids.append(sr.id)
res['result_ids'] = ids
return res
This is how to override default_get for one2many field.
Credit goes to:Default values for one2many
Please read this If you want to set the default values of one2many field from action, you can create a list of tuple with the same format we use for create or write one2many field and then you can pass it to context.
You can copy your context-
context = self.env.context.copy()
Prepare one2many values like this--
pr_lines = []
for pr_line in pr_obj.line_ids: #loop for multiple lines.
pr_lines.append((0,0, {
'purchase_request_id' : pr_obj.id,
'product_id' : pr_line.product_id.id,
'description' : pr_line.name,
'qty_transfer' : pr_line.product_qty,
'uom_id' : pr_line.product_uom_id.id,
}))
You can update your context like this-
context.update({
'default_warehouse_id': self.approving_matrix_id.warehouse.id,
'default_internal_transfer_receipt': pr_lines,
})
in the action you can pass context like
'context' : context,
result_ids = fields.Many2many("schoolresults.detail", "student_id", "School Results", default="_get_subjects")
def get_default_lines(self):
obj = self.env['your.class.name'].search([])
return obj
Try adding many2many field to your class.
I need to take a set of values, in this case the foreign key liquorID in LiquorInStore obtained with values() or values_list() and use them to filter the results by ID of it's parent db, Liquor and return those to the webpage.
This is the view, I fear I may not be using the variables correctly.
def store(request, store_id=1):
a = Store.objects.get(StoreID=store_id)
b = LiquorInStore.objects.filter(storeID__exact=a).values('liquorID')
args = {}
args['liquors'] = Liquor.objects.filter(id__exact=b)
args['a'] = a
return render(request, 'store.html', args)
Here is the models file as well in case that helps.
class LiquorInStore(models.Model):
StoreLiquorID = models.AutoField(primary_key=True)
liquorID = models.ForeignKey(Liquor)
storeID = models.ForeignKey(Store)
StorePrice = models.DecimalField('Store Price', max_digits=5, decimal_places=2)
Do it like this:
b = LiquorInStore.objects.filter(storeID__id=a.id).values_list('liquorID', flat=True)
args['liquors'] = Liquor.objects.filter(id__in=b)
My "Event" object has a "Name" field. There is the possibility that the name is wrong, so a user may suggest a new name. That name gets put into the event's "suggestedN" list. However, I don't want there to be duplicates of one suggestion in that list. I felt like this was a straightforward problem, but for some reason am not finding much success.
Here is how my view currently looks:
#login_required
def suggestName(request):
name = request.POST['name'].strip()
event_id = request.POST['event_id']
try:
e = Event.objects.get(event_id = event_id)
except Event.DoesNotExist:
e = customEvent.objects.get(event_id = event_id)
if name in e.suggestedN.all():
pass
else:
(some code)
Is my if name in e.suggestedN.all() statement wrong?
Here's a brief view of my Event's model:
class Event(models.Model):
def __unicode__(self):
return self.title
suggestedN = models.ManyToManyField('suggestedName', blank = 'TRUE', null = 'TRUE')
class suggestedName(models.Model):
def __unicode__(self):
return self.name
name = models.CharField(max_length=200, blank = 'TRUE', null = 'TRUE')
votes = models.IntegerField(default = 0)
You should use the name attribute on m2m not the m2m itself to compare
#login_required
def suggestName(request):
name = request.POST['name'].strip()
event_id = request.POST['event_id']
try:
e = Event.objects.get(event_id = event_id)
except Event.DoesNotExist:
e = customEvent.objects.get(event_id = event_id)
if name in e.suggestedN.values_list('name', flat=True):
pass
else:
(some code)
I have some external data (SOAP) that I want to show in a model-based-form.
The Model:
class UserProfile(User):
profile_email = models.EmailField()
company_name = models.CharField()
coc_number = models.CharField()
gender = models.CharField()
#etc
The Form:
class UserDetailsForm(forms.ModelForm):
class Meta:
model = UserProfile
The data is a dictionary:
u = {}
u['profile_email'] = 'monkey'
u['company_name'] = 'tiger'
u['coc_number'] = 'some number'
u['gender'] = 'M'
My question is: What is the best way to put the data into the form? What I have so far:
form = UserDetailsForm(initial=u)
This results in a form with all the data.
1) But is this the right way to fill a model-bases-form with external data?
2) How can I set the right value in a select option (Choose country for instance)?
Yes, this is appropriate way.
You need to set value for select/choices field in the dict similar to approach 1.
For example:
COUNTRY_CHOICES = (
('IN', 'India'),
('US', 'USA'),
)
....
#model field
country = models.CharField(choices=COUNTRY_CHOICES)
# then set it in dict as
u = {}
u['country'] = 'IN'
u['profile_email'] = 'monkey'
u['company_name'] = 'tiger'
u['coc_number'] = 'some number'
u['gender'] = 'M'
...