django forms get field output in view - django

I have model form with several fields works as expected. Now I need, for specific reasons, to get form field in view but got error 'EditPostForm' object has no attribute 'about' when I call mydata1 = form.about in view. But about field exist of course. form.data.about also wont work etc. So how can I get it? Thanks.

If you form has instance associated to it, you can try
post = EditPost.objects.get(id=id)
form1 = EditPostForm(instance=post)
form1.instance.about
Based on your comment below if you are using ManyToMany relation you can get the value as
>>> bf = BookForm(instance=book)
>>> bf.instance.authors
<django.db.models.fields.related.ManyRelatedManager object at 0x0000000004658B38>
>>> bf.instance.authors.all() #which returns a query set of related objects
[<Author: Kotian>]
>>> bf.instance.authors.all()[0]
<Author: Kotian>
>>> bf.instance.authors.all()[0].name
u'Kotian'
or based on how you have defined the ManyToMany
>>> af = AuthorForm(instance=author)
>>> af.instance.name
u'MyName'
>>> af.instance.book_set
<django.db.models.fields.related.ManyRelatedManager object at 0x0000000004658C18>
>>> af.instance.book_set.all() # returns queryset
[<Book: Book object>, <Book: Book object>]
>>> af.instance.book_set.all()[0] #accessing first object here
<Book: Book object>
>>> af.instance.book_set.all()[0].name
u'Lepord'

Related

What is difference between objects.all().annotate and objects.annotate?

Currently I am practicing for annotate and have some confusion regarding below code.
>>> b = Book.objects.all().annotate(upper_name = Upper('name'))
>>> b[0].name
'Book1'
>>> b[0].upper_name
'BOOK1'
>>> ba = Book.objects.annotate(upper_name = Upper('name'))
>>> ba[0]
<Book: Book1>
>>> ba[0].name
'Book1'
>>> ba[0].upper_name
'BOOK1'
I am getting same output when not using all() so what is difference between using Book.objects.all() and 'Book.objects.annotate()'.
How doing annotate() on Book objects without all() provide all Book objects.
I have read Django documentation but not able to find any answer.
Thanks.
There is no difference because all actually calls get_queryset on model manager to return queryset. You can check the implementation of BaseManager to see this.
Using all() is preferable because it's guaranteed to return a QuerySet instance that you can further iterate/filter/etc, where using manager returns Manager instance that you can filter/annotate/whatever but can't use in same way as queryset.
Example:
for book in Book.objects:
# this will fail
for book in Book.objects.all():
# this will work

DRF - Serializer fields "source" argument unclear behaviour

So, consider the following:
>>> d = {'macAddress': '00:00:00:00:00:00'}
>>> s = DeviceSerializer(data=d)
>>> s
DeviceSerializer(data={'macAddress':'00:00:00:00:00:00'}):
mac_address = CharField(max_length=20, source='macAddress')
>>> s.is_valid()
False
>>> s.errors
{'mac_address': [ErrorDetail(string='This field is required.', code='required')]}
Based on the simple above example and my current understanding of the source field argument I would expect the mac_address field to be automatically mapped to the macAddress in the input data and the serializer to be valid.
Why this is not the case?
Thanks to anyone willing to help out :)
It is just the other way around. source is what is on the python side and the field name on the external/API side.
data = {'mac_address':'00:00:00:00:00:00'}
would lead to:
validated_data == {'macAddress':'00:00:00:00:00:00'}

how to get django field type instead of database field type

I have the following code for my url field:
model = MyModel()
field = model._meta.get_field_by_name('my_url_field')[0]
my_type = field.get_internal_type()
print my_type
This prints:
CharField
How can I get the django value of URLField?
It seems the only way to achieve what you want would be to do this:
>>> model = MyModel()
>>> field = model._meta.get_field_by_name('my_url_field')[0]
>>> print field.__class__.__name__
'URLField'

django: use a string to select a specifc model

What I want to do be able to use the name of a model as an input to a function so the objects methods can be performed against the specified model. For example:
from app.models import model1, model2
def select_all_from_model(model_name):
all = model_name.objects.all()
return all
all = select_all_from_model('model1')
all = model_name.objects.all() is a nonsense line. I need to have a model object, not a string name, for the objects.all() select to work. How do I load the model object based on the string value of model_name?
You can use models.get_model() function:
>>> model_class = models.get_model('App', 'Model1')
>>> model_class.objects.all()
>>> [...]
That's if you need to use a string. But you can pass classes around in python. Here's an example:
>>> from app.models import Model1
>>> select_all_from_model(Model1)
>>> [...]

Don't queryset records get ids when saved?

In Rails, and in symfony with Doctrine, you can save a record and then you'll have the record's id. For example:
b = Bank.new
b.save
#b.id now has a value
But in Django that's apparently not how it works:
>>> b = Bank()
>>> b.name = "Fred's Bank"
>>> b.identifier = "fred"
>>> b.save()
>>> b.id
>>> b.id.__class__
<type 'NoneType'>
>>>
As you can see, b.id evaluates to nothing. Do I have to go back and select the id if I want it? That would be a pain in the ass, especially for tables that have a lot of columns.
That is how it works in Django. Assuming that Bank is a Django model, it does get an ID on save, and the current instance reflects that. I can't imagine what you have done to break that. You'll need to post the code of the Bank model.