@permission_required("core.manage_shop")
def manage_properties(request, product_id, template_name="manage/product/properties.html"):
    """Displays the UI for manage the properties for the product with passed
    product_id.
    """
    product = get_object_or_404(Product, pk=product_id)

    # Generate lists of properties. For entering values.
    display_configurables = False
    display_filterables = False
    display_displayables = False
    configurables = []
    filterables = []
    displayables = []
    product_variant_properties = []

    # Configurable
    if not product.is_product_with_variants():
        for property_group in product.property_groups.all():
            properties = []
            for prop in property_group.properties.filter(configurable=True).order_by("groupspropertiesrelation"):
                display_configurables = True

                try:
                    ppv = ProductPropertyValue.objects.get(property=prop,
                                                           property_group=property_group,
                                                           product=product,
                                                           type=PROPERTY_VALUE_TYPE_DEFAULT)
                except ProductPropertyValue.DoesNotExist:
                    ppv_id = None
                    ppv_value = ""
                else:
                    ppv_id = ppv.id
                    ppv_value = ppv.value

                # Mark selected options
                options = []
                for option in prop.options.all():
                    if str(option.id) == ppv_value:
                        selected = True
                    else:
                        selected = False

                    options.append({
                        "id": option.id,
                        "name": option.name,
                        "selected": selected,
                    })

                properties.append({
                    "id": prop.id,
                    "name": prop.name,
                    "title": prop.title,
                    "type": prop.type,
                    "options": options,
                    "display_number_field": prop.type == PROPERTY_NUMBER_FIELD,
                    "display_text_field": prop.type == PROPERTY_TEXT_FIELD,
                    "display_select_field": prop.type == PROPERTY_SELECT_FIELD,
                    "value": ppv_value,
                })

            if properties:
                configurables.append({
                    "id": property_group.id,
                    "name": property_group.name,
                    "properties": properties,
                })

        # Filterable
        for property_group in product.property_groups.all():
            properties = []
            for prop in property_group.properties.filter(filterable=True).order_by("groupspropertiesrelation"):

                display_filterables = True

                # Try to get the value, if it already exists.
                ppvs = ProductPropertyValue.objects.filter(property=prop,
                                                           property_group=property_group,
                                                           product=product,
                                                           type=PROPERTY_VALUE_TYPE_FILTER)
                value_ids = [ppv.value for ppv in ppvs]

                # Mark selected options
                options = []
                for option in prop.options.all():

                    if str(option.id) in value_ids:
                        selected = True
                    else:
                        selected = False

                    options.append({
                        "id": option.id,
                        "name": option.name,
                        "selected": selected,
                    })

                value = ""
                if prop.type == PROPERTY_SELECT_FIELD:
                    display_select_field = True
                else:
                    display_select_field = False
                    try:
                        value = value_ids[0]
                    except IndexError:
                        pass

                properties.append({
                    "id": prop.id,
                    "name": prop.name,
                    "title": prop.title,
                    "type": prop.type,
                    "options": options,
                    "value": value,
                    "display_on_product": prop.display_on_product,
                    "display_number_field": prop.type == PROPERTY_NUMBER_FIELD,
                    "display_text_field": prop.type == PROPERTY_TEXT_FIELD,
                    "display_select_field": display_select_field,
                })
            if properties:
                filterables.append({
                    "id": property_group.id,
                    "name": property_group.name,
                    "properties": properties,
                })

        # Displayable
        for property_group in product.property_groups.all():
            properties = []
            for prop in property_group.properties.filter(display_on_product=True).order_by("groupspropertiesrelation"):

                display_displayables = True

                # Try to get the value, if it already exists.
                ppvs = ProductPropertyValue.objects.filter(property=prop,
                                                           property_group=property_group,
                                                           product=product,
                                                           type=PROPERTY_VALUE_TYPE_DISPLAY)
                value_ids = [ppv.value for ppv in ppvs]

                # Mark selected options
                options = []
                for option in prop.options.all():

                    if str(option.id) in value_ids:
                        selected = True
                    else:
                        selected = False

                    options.append({
                        "id": option.id,
                        "name": option.name,
                        "selected": selected,
                    })

                value = ""
                if prop.type == PROPERTY_SELECT_FIELD:
                    display_select_field = True
                else:
                    display_select_field = False
                    try:
                        value = value_ids[0]
                    except __HOLE__:
                        pass

                properties.append({
                    "id": prop.id,
                    "name": prop.name,
                    "title": prop.title,
                    "type": prop.type,
                    "options": options,
                    "value": value,
                    "filterable": prop.filterable,
                    "display_number_field": prop.type == PROPERTY_NUMBER_FIELD,
                    "display_text_field": prop.type == PROPERTY_TEXT_FIELD,
                    "display_select_field": display_select_field,
                })

            if properties:
                displayables.append({
                    "id": property_group.id,
                    "name": property_group.name,
                    "properties": properties,
                })

    if product.is_variant():
        product_variant_properties_dict = {}
        qs = ProductPropertyValue.objects.filter(product=product, type=PROPERTY_VALUE_TYPE_VARIANT)
        for ppv in qs:
            try:
                property_option = PropertyOption.objects.get(property_id=ppv.property_id, pk=ppv.value)
                property_group_name = ppv.property_group.name if ppv.property_group_id else ''
                group_dict = product_variant_properties_dict.setdefault(ppv.property_group_id or 0,
                                                                       {'property_group_name': property_group_name,
                                                                        'properties': []})
                group_dict['properties'].append(property_option)
            except (ProductPropertyValue.DoesNotExist, PropertyOption.DoesNotExist):
                continue

        groups = product_variant_properties_dict.values()
        sorted_groups = sorted(groups, key=lambda group: group['property_group_name'])
        for group in sorted_groups:
            product_variant_properties.append(group)

    # Generate list of all property groups; used for group selection
    product_property_group_ids = [p.id for p in product.property_groups.all()]
    shop_property_groups = []
    for property_group in PropertyGroup.objects.all():

        shop_property_groups.append({
            "id": property_group.id,
            "name": property_group.name,
            "selected": property_group.id in product_property_group_ids,
        })

    return render_to_string(template_name, RequestContext(request, {
        "product": product,
        "filterables": filterables,
        "display_filterables": display_filterables,
        "configurables": configurables,
        "display_configurables": display_configurables,
        "displayables": displayables,
        "display_displayables": display_displayables,
        "product_property_groups": product.property_groups.all(),
        "shop_property_groups": shop_property_groups,
        "product_variant_properties": product_variant_properties
    }))
dataset/ETHPy150Open diefenbach/django-lfs/lfs/manage/product/properties.py/manage_properties