Multiple document uploads to Wagtail Page - document

Hi I am new to Wagtail and wondered if there is a simple way of adding multiple downloads to a single page type. I have created a custom page type and would like to be able to add several documents/downloads. I have managed to get one to show, but can find no way of this being extended to add many.
downloads = models.ForeignKey('wagtaildocs.Document', null=True, on_delete=models.SET_NULL)
content_panels = Page.content_panels + [
DocumentChooserPanel('downloads'),

You can do this with a child model associated with your page model, via a ParentalKey and an InlinePanel. The tutorial at http://docs.wagtail.io/en/v1.10.1/getting_started/tutorial.html#images gives an example of this - your setup is very similar, with the only real difference being that you're linking documents to the page rather than images:
class MyPage(Page):
...
content_panels = Page.content_panels + [
InlinePanel('documents', label="Documents")
]
class MyPageDocumentLink(Orderable):
page = ParentalKey(MyPage, related_name='documents')
document = models.ForeignKey(
'wagtaildocs.Document', on_delete=models.CASCADE, related_name='+'
)
panels = [
DocumentChooserPanel('document'),
]

Related

Wagatail Custom User models not displaying ModelChoiceField

Im using wagtail 4.1 & Django 4.1
I'm trying to create a custom User model which selects from a Snippet I have created.
class User(AbstractUser):
custiommodel= models.ForeignKey(CustomModel, on_delete=models.SET_NULL, null=True, blank=False)
user_type = models.CharField(blank=False, null=False, max_length=20, choices=USER_TYPE_CHOICES)
panels = [
FieldPanel('custommodel'),
FieldPanel('user_type'),
]
class CustomUserCreationForm(UserCreationForm):
user_type = forms.ChoiceField(required=True, choices=USER_TYPE_CHOICES, label=_("User Type"))
custommodel = forms.ModelChoiceField(queryset=CustomModel.objects, required=True,
label=_("Select Organisation"))
In my settings I have
WAGTAIL_USER_EDIT_FORM = 'users.forms.CustomUserEditForm'
This used to previously work on older versions of wagtail. Now the only custom filed i can see from above is 'user_type' which means it's finding the correct file but won't display custom models.
Is this related to this bug which won't allow me to directly register_snipets in the model file but instead in 'wagtail_hooks.py' through view sets?

Two properties that relate to each other in another model

Sorry that the title might be confusing but I'm not native english speaker and very new to django terms.
I have a scenario like this: A department can have many branches. I have a student model where he has two properties, Department and Branch.
When I select his department , I want it to accept (and show in admin panel) only the branches that are related to that department , my code so far is this:
class Entity(models.Model):
id = models.UUIDField(primary_key=True , default = uuid.uuid4, editable=False)
class Department(Entity):
name = models.CharField(max_length=100, null=False)
class Branch(Entity):
name = models.CharField(max_length=100, null=False)
dep = models.ForeignKey(Department, related_name='branches', on_delete=models.CASCADE)
class Student(Entity):
#Some Fields here
department = models.ForeignKey(Department, related_name='students', on_delete=models.CASCADE)
branch = models.ForeignKey(Branch, related_name='students', on_delete=models.CASCADE)
Assuming I have a 2 departments (CE and CS), CE has 2 branches and CS has 3 branches , What I want is, when I choose a student's department in the admin panel, I want the branches to be shown (to select from) only the one that exists on that department , what I'm getting is 5 branches (in this example).
How can I solve this ?
NOTE: I haven't played with anything related to the admin panel except registering the models.
Thanks in advance and sorry if the title or any other part is not very correct.
There are two solutions:
override save() function and check branch.
Check branch inside form by overriding clean_branch()
It's better to implement both.

Django dynamic form subclass list

I'm trying to understand how can I define model as a class containing 2 integers and 1 charfield and then make it a part of another model.
Example of data I need
I guess in object oriented programming I should define model class like this:
class Component(models.Model):
pipe_type = models.CharField(max_length=200)
length = models.IntegerField()
amount = models.IntegerField()
And then I don't know how can I use it with django models, it should be something like this:
class Item(models.Model):
name = models.CharField()
components_needed = ? LIST OF Component class ?
Also, since components needed size will wary for objects, it should be possible to extend it's size with button on a page, for example there could be 3 input fields and next to them would be "+" and "-" button to add/remove another set of 3 input fields
I spent entire day looking for solution, but at this point I'm not sure if django can handle this. I'm new to python and django, so there are many things I do not understand.
I will be grateful for any kind of help
the only way now( you canot put multi FK in one cell) is like django itself using with user/groups so you need 3 models.
in django there is group, user and user_group so i suggesting for you:
class Component(models.Model):
pipe_type = models.CharField(max_length=200)
length = models.IntegerField()
amount = models.IntegerField()
class Item(models.Model):
name = models.CharField()
class Item_Component(models.Model):
Component = models.ForeignKey(Component, on_delete=models.CASCADE)
Item = models.ForeignKey(Item, on_delete=models.CASCADE)
so now in third model you can have multiple rows with item and with diffrent component.
open yours db viewer app and see django user_group table.

Django Admin - Include field of a model A when adding a record of model B

I'm working on legacy code which is in Django (1.11)
I have a model A, with attributes:
Model_A:
Name (NOT NULL)
City (NOT NULL)
FieldX (Nullable) - CharField
And a model B, with attributes:
Model_B:
Name (NOT NULL)
City (NOT NULL)
RelatedField (ForeignKey to an instance of Model_A)
Now, When I add a record for Model_A then I may NOT need to fill FieldX.
However, When I add a record for Model_B then I'll have to select an instance of Model_A and then if FieldX of that instance is NULL then I have to fill that as well (make it mandatory).
The form for Model_A is pretty straight forward.
But for Model_B I need a form where:
First an instance of Model_A is selected (Dropdown)
The input box for FieldX of instance selected in 1 is shown (Editable and mandatory to fill, blank=False).
The rest of the fields are shown (Name, City, FieldY).
Can this be done using the admin page? Or will I have to create proper forms and user flow for this?
I have not tested this, but you should be able to do the following:
from django.contrib import admin
class ModelAForm(ModelForm):
FieldX = CharField(
required=True
)
class Meta:
model = Model_A
fields = ['FieldX']
class ModelAInline(admin.StackedInline):
model = Model_A
form = ModelAForm
class ModelBAdmin(admin.ModelAdmin):
inlines = [
ModelAInline
]
admin.site.register(ModelB, ModelBAdmin)
For model B I'd override the view and form in order to achieve this in admin site.
model_b_view = ModelBView.as_view()
#admin.register(Model_B)
class Model_B_Admin(admin.ModelAdmin):
def get_urls(self):
urls = super().get_urls()
my_urls = [
url(r'^add/$',
self.admin_site.admin_view(model_b_view)),
]
return my_urls + urls
Where ModelBView is a template view, and you'd have to override get and post of it, In get send all instances of Model_A to template and handle via jquery there.

Where is odoo stored keywords and urls

I cannot understand where stored keywords and urls.
For example in module website exist class website_seo_metadata. It has such columns:
'website_meta_title': fields.char("Website meta title", translate=True),
'website_meta_description': fields.text("Website meta description", translate=True),
'website_meta_keywords': fields.char("Website meta keywords", translate=True),
When I added some keywords for page records not exist in DB.
I can not understand where stored urls for pages. I know, if I create route:
#http.route('/contacts/', type='http', auth="public", website=True)
this path was added to sitemap.xml
For generate sitemap.xml used sitemap_xml_index method:
#http.route('/sitemap.xml', type='http', auth="public", website=True)
def sitemap_xml_index(self):
current_website = request.website
cr, uid, context = request.cr, openerp.SUPERUSER_ID, request.context
ira = request.registry['ir.attachment']
iuv = request.registry['ir.ui.view']
But in this tables not present any one url. I can not understanding how it generate path for all pages. Where is it data stored?
I wrote own module but pages from it not present in sitemap.xml and keywords not correctly saved and displayed.
I tried extend my models such as:
class pr_info_pages(models.Model):
_name = 'pr_filials.pr_info_pages'
_inherit = ['mail.thread', 'website.seo.metadata', 'website.published.mixin']
but nothing changed...
How i can add my urls to sitemap and normally store keywords?
For keywords you need use in model:
_inherit = ['mail.thread', 'website.seo.metadata']
Also, when you generate page data you need put to page 'main_object'. This is the dictionary element that contains the object of your model. For example:
return http.request.render(_your_template_, {
'page_data': page_data,
'main_object': _object_
})

Resources