rendering foreign field in django form - django

I have a model where a field references a foreign key from another model as:
class DummyModel(models.Model):
name = models.CharField(max_length=100)
description = models.CharField(max_length=150)
image_type = models.ForeignKey(ImageTypeModel) # Foreign key
class Meta:
db_table = "dummy"
The parent model is also simple:
class ImageTypeModel(models.Model):
name = models.CharField(max_length=100)
dims = models.IntegerField()
class Meta:
db_table = "imagetypes"
Now, I attempt to render a record in a form and for that purpose I am using django-crispy-forms. So, I have:
class DummyForm(ModelForm):
class Meta:
model = DummyModel
fields = ['name', 'description', 'image_type']
def __init__(self, *args, **kwargs):
super(DummyForm, self).__init__(*args, **kwargs)
self.helper = FormHelper(self)
self.helper.form_class = 'form-horizontal'
self.helper.label_class = 'col-sm-2'
self.helper.field_class = 'col-sm-10'
#self.helper.form_tag = False
self.helper.layout = Layout(
Field('name'),
Field('description'),
Field('image_type'))
The image_type field renders as a drop-down list which is perfect but instead of the name of the image types, the entries are all labelled ImageTypeModel. Is there a mechanism so that I can display the corresponding name from the ImageTypeModel record but when the form is saved it saves the primary key rather than the name.

You should implement the __unicode__ (python 2) or __str__ (python 3) method inside the model.
Like this:
class ImageTypeModel(models.Model):
name = models.CharField(max_length=100)
dims = models.IntegerField()
class Meta:
db_table = "imagetypes"
# For Python 2
def __unicode__(self):
return self.name
# For Python 3
def __str__(self):
return self.name

Related

Queryset from non-related model in __init__ modelform method

I have two model classes. They are not related models (no relationship).
# models.py
class Model1(models.Model):
description = models.TextField()
option = models.CharField(max_length=64, blank=False)
def __str__(self):
return self.option
class Model2(models.Model):
name = models.CharField(max_length=64, blank=False)
def __str__(self):
return self.name
I have respective form from where I am submitting and saving data in my table. I want to use my Model2 data to fill-in 'option' field as select field, so I am introducing below init method.
# forms.py
class Model1Form(forms.ModelForm):
def __init__(self, *args, **kwargs):
all_options = Model2.objects.all()
super(Model1Form, self).__init__(*args, **kwargs)
self.fields['option'].queryset = all_options
class Meta:
model = Model1
fields = ('description', 'option')
It does not render the dropdown on my template, so I am wondering whether it is right way to address the issue (acknowledging that models are not related to each other).

Forwading ManyToMany model field in django-autocomplete-light

models.py
class InvestmentGroup(models.Model):
name = models.CharField(max_length=200, blank=True, null=True)
persons = models.ManyToManyField('Person', blank=True, related_name='investment_groups')
lead_investor = models.ForeignKey(
'Person', blank=True, null=True, on_delete=models.CASCADE, related_name='lead_investment_groups'
)
forms.py
class InvestmentGroupModelForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(InvestmentGroupModelForm, self).__init__(*args, **kwargs)
class Meta:
model = models.InvestmentGroup
fields = '__all__'
widgets = {
"lead_investor": autocomplete.ModelSelect2(
url="lead-investor-autocomplete",
forward=["persons"]
)
}
AutoCompleteview
class LeadInvestorAutoComplete(autocomplete.Select2QuerySetView):
def get_queryset(self):
# Don't forget to filter out results depending on the visitor !
if not self.request.user.is_authenticated:
return models.Person.objects.none()
qs = models.Person.objects.all()
persons = self.forwarded.get('persons', None)
print(persons) # Output: []
if persons:
qs = qs.filter(person__in=persons)
return qs
I am getting empty values if I forward many to many field like this but works for other fields like name or foreign keys.
Is it possible to forward ManyToMany field?
You're not forwarding the persons field, which is why it seems to be empty.
If you change your form to this, it should work:
class InvestmentGroupModelForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(InvestmentGroupModelForm, self).__init__(*args, **kwargs)
class Meta:
model = models.InvestmentGroup
fields = '__all__'
widgets = {
"lead_investor": autocomplete.ModelSelect2(
url="lead-investor-autocomplete",
forward=["persons"]
)
}

Set a field value within form __init__ function

I am trying to find out an efficient way to set a field value within form init method. My models are similar to below
class Users(models.Model):
firstname = models.CharField()
lastname = models.CharField()
class profile(models.model):
user = models.ForeignKey(Users, on_delete=models.PROTECT)
class logindetails(models.model):
user = models.ForeignKey(Users, on_delete=models.PROTECT)
profile = models.ForeignKey(profile, on_delete=models.PROTECT)
login_time = models.DateField(auto_now=True)
My form is like as below:
class LoginForm(forms.ModelForm):
class Meta:
model = logindetails
fields = [__all__]
def __init__(self, *args, **kwargs):
self._rowid = kwargs.pop('rowid', None)
super(LoginForm, self).__init__(*args, **kwargs)
instance = profile.objects.get(id=self._rowid)
self.fields['user'] = instance.user <--- Facing difficulties here
Any help will be appreciated.
Django had built-in ways of setting initial form values, the documentation is available here: https://docs.djangoproject.com/en/3.0/ref/forms/api/#dynamic-initial-values

Show all languages in form using django-translations

I am using django-translations for translating some fields of my model.
Using the Django Admin I can enter the translations and the form in the frontend shows the matching language values.
But I want to show one field for each language "similar" to the Django Admin, except I don't want to manually add the fields for non translated languages.
So if I have the languages en (default) and de I want to output title or title_en and title_de as fields.
I tried to add the translation fields myself e.g. title_de to the model, layout and meta class, but it didn't work.
How can I show all the fields for different languages simultaneously?
Model
class Category(Translatable, MPTTModel):
title = models.CharField(max_length=200)
slug = models.SlugField()
parent = TreeForeignKey('self', on_delete=models.CASCADE, null=True, blank=True, related_name='children')
class Meta:
# enforcing that there can not be two categories under a parent with same slug
unique_together = ('slug', 'parent',)
class MPTTMeta:
order_insertion_by = ['title']
class TranslatableMeta:
fields = ['title', 'slug']
Form
class CategoryForm(forms.ModelForm):
use_required_attribute = False
title = forms.CharField(max_length=200)
slug = forms.SlugField(help_text=_('Will be generated automatically from the title'))
def __init__(self, *args, **kwargs):
self.helper = FormHelper()
self.helper.form_method = 'post'
self.helper.form_action = '.'
self.helper.form_class = 'form-horizontal form-bordered'
self.helper.label_class = 'col-lg-3'
self.helper.field_class = 'col-lg-8'
self.helper.layout = self.__get_layout()
super().__init__(*args, **kwargs)
self.fields['title'].required = True
self.fields['slug'].required = True
#staticmethod
def __get_layout():
layout = Layout(
Field('title'),
Field('title_de'),
Field('slug', readonly=''),
ButtonHolder(
Submit('submit', _('Save'))
)
)
return layout
def clean(self):
cleaned_data = super().clean()
return cleaned_data
class Meta:
model = Category
fields = ['title', 'slug']
According to the docs, you should be able to use ModelForms

How to filter or query using abstract parent class in Django model?

This one is interesting to solve. I am building a module to register address for hospital, medical store and doctors. There is an abstracted model PrimaryAddress and a subclass called MedicalStorePrimaryAddress, and more subclasses will use the same abstracted model. I am using django rest framework to get the listings based on proximity (latitude, longitude and city). Now how could I filter it all using parent class, i.e PrimaryAddress model as I want to filter all the entities, i.e hospital, medical store and doctor nearby.
I have looked into django-polymorphic library but it doesnt help with geodjango and abstract class.
Any help suggestion is appreciated. Thanks
Here is the code sample:
# MODELS
class PrimaryAddress(gismodels.Model):
street = gismodels.CharField(max_length=255)
city = gismodels.CharField(max_length=60)
state = gismodels.CharField(max_length=100,
choices=settings.US_STATES,
default="CT")
landmark = gismodels.TextField()
latitude = gismodels.FloatField(null=True, blank=True)
longitude = gismodels.FloatField(null=True, blank=True)
location = gismodels.PointField(null=True, blank=True)
objects = gismodels.GeoManager()
def __unicode__(self):
return self.street
class Meta:
verbose_name = "Address"
verbose_name_plural = "Addresses"
abstract = True
def save(self, *args, **kwargs):
if self.latitude and self.longitude:
self.location = Point(self.longitude, self.latitude)
super(PrimaryAddress, self).save(*args, **kwargs)
class MedicalStoreAddress(PrimaryAddress):
medical_store = gismodels.OneToOneField(MedicalStore, related_name="medical_store_address",
on_delete=gismodels.CASCADE, null=True, blank=True)
# objects = gismodels.GeoManager()
def __unicode__(self):
return self.street
class Meta:
verbose_name = "Medical Store Address"
verbose_name_plural = "Medical Store Addresses"
def save(self, *args, **kwargs):
if self.latitude and self.longitude:
self.location = Point(self.longitude, self.latitude)
super(MedicalStoreAddress, self).save(*args, **kwargs)
# VIEW
class ProximityFilter(ListAPIView):
serializer_class = AddressSerializer
# authentication_classes = (authentication.TokenAuthentication, authentication.SessionAuthentication,)
# permission_classes = (permissions.IsAuthenticated,)
pagination_class = StandardResultsSetPagination
def get_queryset(self):
longitude = self.kwargs.get('longitude')
latitude = self.kwargs.get('latitude')
city = self.kwargs.get('city')
current_point = GEOSGeometry('POINT(%s %s)' % (longitude, latitude), srid=4326)
# raise
queryset = MedicalStoreAddress.objects.filter(city__iexact=city, location__distance_lte=(current_point, D(mi=700000000))).distance(
current_point).order_by('distance')
return queryset
# SERIALIZER
class AddressSerializer(HyperlinkedModelSerializer):
class Meta:
model = DoctorPrimaryAddress
fields = ('pk', 'street', 'latitude', 'longitude', 'city')
This paste expires on 2018-03-29 21:26:23. View raw. Remove now (Why am I seeing this?) Pasted through web.