How can I add customised choice fields in django (2.1)? - django

This is the model class that stores the details about an app. In this model is it possible to add a customised list fields. i,e a user should be able to define a set of choices and later it will be available for adding (as tags) to the builds of the app.
class App(models.Model):
bundle_number = models.CharField(max_length=255)
hidden = models.BooleanField(default=False)
class Build(models.Model):
app = models.ForeignKey(App, on_delete=models.CASCADE)
number = models.CharField(max_length=255)
uploaded_date = models.DateTimeField(auto_now_add=True)

If I understand your question right you want to do create a new model Tag with builds attribute:
class Tag(models.Model):
...
builds = models.ManyToManyField(Build, related_name="tags")
Then you can assign multiple tags to one build and vice versa multiple builds to one tag.
You can read more here: https://docs.djangoproject.com/en/3.0/ref/models/fields/#django.db.models.ManyToManyField

Related

Customizing Django GenericRelation content_type values in Admin add/change view

My models are using GenericForeignKey and GenericRelations. For simplification my models structure is following:
class BaseModel(models.Model):
name = models.CharField(max_length=100)
model_labels = models.GenericRelation('ModelLabel', related_query_name='%(class)s')
model_types = models.GenericRelation('ModelType'), related_query_name='%(class)s')
class Meta:
abstract = True
class ModelA(BaseModel):
fieldA = models.CharField(max_length = 50)
class ModelB(BaseModel):
fieldB = models.CharField(max_length = 50)
class ModelLabel(models.Model);
label = models.CharField(max_length = 50)
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
object_id = models.PositiveIntegerField()
model_object = GenericForeignKey('content_type', 'object_id')
class ModelType(models.Model):
type = models.CharField(max_length = 50)
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
object_id = models.PositiveIntegerField()
model_object = GenericForeignKey('content_type', 'object_id')
class Unrelated(models.Model):
name = models.CharField(max_lenght = 50)
The problem I am facing is in admin view for ModelLabel and ModelType. Right now, out-of-the-box I am getting 3 fields: Label or Type, Content type and Object id. Yes, this is correct according to the model.
But in Content type I am getting not only ModelA and ModelB as an options. I'm also getting Unrelated and most of the individual fields of different models. According to documentation:
Instances of ContentType represent and store information about the
models installed in your project, and new instances of ContentType are
automatically created whenever new models are installed.
According to this Unrelated can appear in the values, but models' fields shouldn't. So why they appear?
However, this is not the main problem I am struggling with. I'd like to narrow the list of options to choose from in Content type just to ModelA and ModelB. From what I gathered since this is ForeignKey under the hood I should be able to go with ModelChoiceField, but I would need to make it use some hardcoded QuerySet but I cannot find how to make it e.g. from dictionary. Similar goes with Object id, where I'd like to be able to select what value I want to use based on available numbers.
So far I realized that most likely I need to extend admin.ModelAdmin view and most likely also create custom form (extend forms.ModelForm). This is also theory because so far I couldn't figure a way to get mentioned custom QuerySet or Object id. Also there is some drawback of this approach, because if I'll choose to go with this, I'll need to have custom form for every model (ModelLabel, ModelType) - is this really necessary?
I know of a way to add GenericInlineModelAdmin class, but this view allows to add object of type ModelLabel together with ModelB. This doesn't cover case where object of type ModelB already exists.
To summarize what are main goals I want to achieve:
Fix Admin view to create ModelLabel and ModelType
Narrow list of options for Content type field to ModelA and ModelB
Allow user to choose only existing IDs for Object id field

Create forms from model, save to another

I'm building a survey-type app, where the questions are entered/stored in a model (by an admin). I want to use this model to auto-create a user facging form (the response will be stored in another model.
class Question(models.Model):
question_text = models.CharField(max_length=150)
questionnaire = models.ForeignKey(Questionnaire) # 'lump' questions together
class Response(models.Model):
question = models.ForeignKey(Question)
response_text = models.CharField(max_length=150)
user = models.IntegerField() # used to record user ID
I'm not sure what's the correct approach - using a ModelForm (populating through init) or a 'regular' form - where I'm not sure how I output my results - using print or adding to a form property.
Thanks.
In your init you can
self.fields['your_field']=forms.ModelChoiceField(queryset=YourQuerySet.objects.get(pk=X)) // alternatively a filter with first()
to enforce the initial foreign key object

Django forms with odd model relationship

I am working with an existing database that I can not modify and having some trouble trying to deal with presenting forms for modifying the database in Django. The structure in question is as follows and all models are unmanaged.
class Persons(models.Model):
personid = models.BigIntegerField(primary_key=True, db_column='PersonID')
....
class Phones(models.Model):
phoneid = models.BigIntegerField(primary_key=True, db_column='PhoneID')
number = models.CharField(max_length=60, db_column='Number', blank=True)
type = models.CharField(max_length=15, db_column='Type', blank=True)
...
class Personsphones(models.Model):
personphoneid = models.BigIntegerField(primary_key=True, db_column='PersonPhoneID')
personid = models.ForeignKey(Persons, db_column='PersonID')
phoneid = models.ForeignKey(Phones, db_column='PhoneID')
...
I want to create a form to display all of the 'Phones' associated with a particular 'Persons' and in addition be able to modify/add/remove 'Phones' belonging to a 'Persons'. Right now the only thing I can think of is to display the 'Phones' in a modelformset and then if one is added or removed manually set the 'Personsphones' relation. Any ideas on how to best deal with this model setup?
For making changes to your models you may want to use django-south http://south.aeracode.org/docs/
As far as displaying your 'Phone' under your forms.py you may want to set up class meta like so. With this any changes made to models will reflect on change
class Meta:
model = Persons
exclude = ('user')
In models you may want to use Foreignkey fore relationships between phones and Persons. Better seen in action here https://docs.djangoproject.com/en/dev/ref/models/fields/#foreignkey

Django form linking 2 models by many to many field

I have two models:
class Actor(models.Model):
name = models.CharField(max_length=30, unique = True)
event = models.ManyToManyField(Event, blank=True, null=True)
class Event(models.Model):
name = models.CharField(max_length=30, unique = True)
long_description = models.TextField(blank=True, null=True)
I want to create a form that allows me to identify the link between the two models when I add a new entry. This works:
class ActorForm(forms.ModelForm):
class Meta:
model = Actor
The form includes both name and event, allowing me to create a new Actor and simultaneous link it to an existing Event.
On the flipside,
class EventForm(forms.ModelForm):
class Meta:
model = Event
This form does not include an actor association. So I am only able to create a new Event. I can't simultaneously link it to an existing Actor.
I tried to create an inline formset:
EventFormSet = forms.models.inlineformset_factory(Event,
Actor,
can_delete = False,
extra = 2,
form = ActorForm)
but I get an error
<'class ctg.dtb.models.Actor'> has no ForeignKey to <'class ctg.dtb.models.Event'>
This isn't too surprising. The inlineformset worked for another set of models I had, but this is a different example. I think I'm going about it entirely wrong.
Overall question: How can I create a form that allows me to create a new Event and link it to an existing Actor?
Personally, I would put the ManyToMany on Event to begin with, but to each their own...
As for how to do it, you'd want to write a custom ModelForm (not an inline formset), let's call it EventForm. It would handle all of your event's fields and would also have a ModelChoiceField or ModelMultipleChoiceField to allow selection of the Actor(s) involved. Then in your view you would split out the processing of the Event fields and the ForeignKey/M2M field.
Make sense? alt text http://sonicloft.net/im/52

Django Forms With foreign key

I have 2 models in django, and im also using ModelForm, my question is the second model have a froreignkey of the 1, and i want to have one page when generating the form. It's possible, how to link the two forms in one page.
Class Event(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField()
class Date(models.Model):
id = models.AutoField(primary_key=True)
start = models.DateTimeField()
end = models.DateTimeField()
event = models.ForeignKey("Event")
I also have
class EventForm(ModelForm)
Class Date(ModelForm)
What i want is to create the event in one page in my templates.
Thanks.
If you want to have this on the Django Admin, then you need to use inline models.
If you plan to create your own form (using ModelForms), then you need to use inline formets.