You've already forked WhereToGoRedux
mirror of
https://github.com/Llloooggg/WhereToGoRedux.git
synced 2026-03-06 04:56:23 +03:00
Добавлен базовый фронтенд
This commit is contained in:
@@ -1,13 +1,12 @@
|
|||||||
from django.contrib.gis.db import models
|
|
||||||
from django.forms.widgets import Textarea
|
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
|
|
||||||
|
|
||||||
from facilities.models import Facility
|
from facilities.models import Facility
|
||||||
|
|
||||||
|
from facilities.forms import FacilityLocationForm
|
||||||
|
|
||||||
|
|
||||||
class FacilityAdmin(admin.ModelAdmin):
|
class FacilityAdmin(admin.ModelAdmin):
|
||||||
formfield_overrides = {models.PointField: {"widget": Textarea}}
|
form = FacilityLocationForm
|
||||||
|
|
||||||
|
|
||||||
admin.site.register(Facility, FacilityAdmin)
|
admin.site.register(Facility, FacilityAdmin)
|
||||||
|
|||||||
@@ -5,4 +5,4 @@ from django.utils.translation import gettext_lazy as _
|
|||||||
class FacilitiesConfig(AppConfig):
|
class FacilitiesConfig(AppConfig):
|
||||||
default_auto_field = "django.db.models.BigAutoField"
|
default_auto_field = "django.db.models.BigAutoField"
|
||||||
name = "facilities"
|
name = "facilities"
|
||||||
verbose_name = _("Facilities")
|
verbose_name = _("facilities")
|
||||||
|
|||||||
40
backend/wheretogo/facilities/forms.py
Normal file
40
backend/wheretogo/facilities/forms.py
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
from django import forms
|
||||||
|
from django.contrib.gis.geos import Point
|
||||||
|
|
||||||
|
from facilities.models import Facility
|
||||||
|
|
||||||
|
|
||||||
|
class FacilityLocationForm(forms.ModelForm):
|
||||||
|
|
||||||
|
latitude = forms.FloatField(
|
||||||
|
min_value=-90,
|
||||||
|
max_value=90,
|
||||||
|
required=True,
|
||||||
|
)
|
||||||
|
longitude = forms.FloatField(
|
||||||
|
min_value=-180,
|
||||||
|
max_value=180,
|
||||||
|
required=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
class Meta(object):
|
||||||
|
model = Facility
|
||||||
|
exclude = []
|
||||||
|
widgets = {"location": forms.HiddenInput()}
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
coordinates = self.initial.get("location", None)
|
||||||
|
if coordinates:
|
||||||
|
(
|
||||||
|
self.initial["longitude"],
|
||||||
|
self.initial["latitude"],
|
||||||
|
) = coordinates.tuple
|
||||||
|
|
||||||
|
def clean(self):
|
||||||
|
data = super().clean()
|
||||||
|
longitude = data.get("longitude")
|
||||||
|
latitude = data.get("latitude")
|
||||||
|
if latitude and longitude:
|
||||||
|
data["location"] = Point(longitude, latitude)
|
||||||
|
return data
|
||||||
@@ -4,12 +4,11 @@ from django.db import models
|
|||||||
|
|
||||||
|
|
||||||
class Facility(models.Model):
|
class Facility(models.Model):
|
||||||
name = models.CharField(max_length=200)
|
name = models.CharField(max_length=200, verbose_name=_("name"))
|
||||||
address = models.CharField(max_length=100)
|
address = models.CharField(max_length=100, verbose_name=_("address"))
|
||||||
city = models.CharField(max_length=50)
|
city = models.CharField(max_length=50, verbose_name=_("city"))
|
||||||
location = gis_models.PointField(
|
location = gis_models.PointField(
|
||||||
null=True,
|
null=True, blank=True, verbose_name=_("location")
|
||||||
blank=True,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
from rest_framework_gis import serializers
|
from rest_framework.serializers import ModelSerializer
|
||||||
|
|
||||||
from facilities.models import Facility
|
from facilities.models import Facility
|
||||||
|
|
||||||
|
|
||||||
class FacilitySerializer(serializers.GeoFeatureModelSerializer):
|
class FacilitySerializer(ModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Facility
|
model = Facility
|
||||||
fields = ("id", "name", "address", "city")
|
|
||||||
geo_field = "location"
|
geo_field = "location"
|
||||||
|
fields = ("id", "name", "address", "city")
|
||||||
|
|||||||
@@ -6,6 +6,6 @@ app_name = "facilities"
|
|||||||
|
|
||||||
|
|
||||||
router = routers.DefaultRouter()
|
router = routers.DefaultRouter()
|
||||||
router.register("facilities", FacilityViewSet, "facilities")
|
router.register("", FacilityViewSet, "facilities")
|
||||||
|
|
||||||
urlpatterns = router.urls
|
urlpatterns = router.urls
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2022-09-10 03:41+0300\n"
|
"POT-Creation-Date: 2022-09-10 07:27+0300\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
@@ -19,14 +19,26 @@ msgstr ""
|
|||||||
"Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
|
"Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
|
||||||
"%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n"
|
"%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n"
|
||||||
"%100>=11 && n%100<=14)? 2 : 3);\n"
|
"%100>=11 && n%100<=14)? 2 : 3);\n"
|
||||||
#: facilities/apps.py:8
|
#: facilities/apps.py:8 facilities/models.py:16
|
||||||
msgid "Facilities"
|
|
||||||
msgstr "Заведения"
|
|
||||||
|
|
||||||
#: facilities/models.py:16
|
|
||||||
msgid "facility"
|
|
||||||
msgstr "заведение"
|
|
||||||
|
|
||||||
#: facilities/models.py:17
|
|
||||||
msgid "facilities"
|
msgid "facilities"
|
||||||
msgstr "заведения"
|
msgstr "заведения"
|
||||||
|
|
||||||
|
#: facilities/models.py:7
|
||||||
|
msgid "name"
|
||||||
|
msgstr "название"
|
||||||
|
|
||||||
|
#: facilities/models.py:8
|
||||||
|
msgid "address"
|
||||||
|
msgstr "адрес"
|
||||||
|
|
||||||
|
#: facilities/models.py:9
|
||||||
|
msgid "city"
|
||||||
|
msgstr "город"
|
||||||
|
|
||||||
|
#: facilities/models.py:11
|
||||||
|
msgid "location"
|
||||||
|
msgstr "местоположение"
|
||||||
|
|
||||||
|
#: facilities/models.py:15
|
||||||
|
msgid "facility"
|
||||||
|
msgstr "заведение"
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ INSTALLED_APPS = [
|
|||||||
"django.contrib.sessions",
|
"django.contrib.sessions",
|
||||||
"django.contrib.messages",
|
"django.contrib.messages",
|
||||||
"django.contrib.staticfiles",
|
"django.contrib.staticfiles",
|
||||||
|
"django.contrib.gis",
|
||||||
"rest_framework",
|
"rest_framework",
|
||||||
"rest_framework_gis",
|
"rest_framework_gis",
|
||||||
"corsheaders",
|
"corsheaders",
|
||||||
|
|||||||
@@ -19,5 +19,5 @@ from django.urls import include
|
|||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path("admin/", admin.site.urls),
|
path("admin/", admin.site.urls),
|
||||||
path("api/", include("facilities.urls")),
|
path("api/facilities", include("facilities.urls")),
|
||||||
]
|
]
|
||||||
|
|||||||
16
frontend/package-lock.json
generated
Normal file
16
frontend/package-lock.json
generated
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"requires": true,
|
||||||
|
"lockfileVersion": 1,
|
||||||
|
"dependencies": {
|
||||||
|
"n": {
|
||||||
|
"version": "9.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/n/-/n-9.0.0.tgz",
|
||||||
|
"integrity": "sha512-OZie4DuAZASChFZnIkf5BYEYEhMe6utRTAWM+98aS6N0pRLNxcDEMwxSsy7is98zTlDICcQB2dym+u10pEOtBg=="
|
||||||
|
},
|
||||||
|
"stable": {
|
||||||
|
"version": "0.1.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz",
|
||||||
|
"integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
24
frontend/wheretogo/README.md
Normal file
24
frontend/wheretogo/README.md
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
# wheretogo
|
||||||
|
|
||||||
|
## Project setup
|
||||||
|
```
|
||||||
|
npm install
|
||||||
|
```
|
||||||
|
|
||||||
|
### Compiles and hot-reloads for development
|
||||||
|
```
|
||||||
|
npm run serve
|
||||||
|
```
|
||||||
|
|
||||||
|
### Compiles and minifies for production
|
||||||
|
```
|
||||||
|
npm run build
|
||||||
|
```
|
||||||
|
|
||||||
|
### Lints and fixes files
|
||||||
|
```
|
||||||
|
npm run lint
|
||||||
|
```
|
||||||
|
|
||||||
|
### Customize configuration
|
||||||
|
See [Configuration Reference](https://cli.vuejs.org/config/).
|
||||||
5
frontend/wheretogo/babel.config.js
Normal file
5
frontend/wheretogo/babel.config.js
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
module.exports = {
|
||||||
|
presets: [
|
||||||
|
'@vue/cli-plugin-babel/preset'
|
||||||
|
]
|
||||||
|
}
|
||||||
20
frontend/wheretogo/jsconfig.json
Normal file
20
frontend/wheretogo/jsconfig.json
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "es5",
|
||||||
|
"module": "esnext",
|
||||||
|
"baseUrl": "./",
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"paths": {
|
||||||
|
"@/*": [
|
||||||
|
"src/*"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"lib": [
|
||||||
|
"esnext",
|
||||||
|
"dom",
|
||||||
|
"dom.iterable",
|
||||||
|
"scripthost"
|
||||||
|
],
|
||||||
|
"jsx": "preserve"
|
||||||
|
}
|
||||||
|
}
|
||||||
19941
frontend/wheretogo/package-lock.json
generated
Normal file
19941
frontend/wheretogo/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
44
frontend/wheretogo/package.json
Normal file
44
frontend/wheretogo/package.json
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
{
|
||||||
|
"name": "wheretogo",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"serve": "vue-cli-service serve",
|
||||||
|
"build": "vue-cli-service build",
|
||||||
|
"lint": "vue-cli-service lint"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"axios": "^0.27.2",
|
||||||
|
"core-js": "^3.8.3",
|
||||||
|
"vue": "^3.2.13"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@babel/core": "^7.12.16",
|
||||||
|
"@babel/eslint-parser": "^7.12.16",
|
||||||
|
"@vue/cli-plugin-babel": "~5.0.0",
|
||||||
|
"@vue/cli-plugin-eslint": "~5.0.0",
|
||||||
|
"@vue/cli-service": "~5.0.0",
|
||||||
|
"eslint": "^7.32.0",
|
||||||
|
"eslint-plugin-vue": "^8.0.3"
|
||||||
|
},
|
||||||
|
"eslintConfig": {
|
||||||
|
"root": true,
|
||||||
|
"env": {
|
||||||
|
"node": true
|
||||||
|
},
|
||||||
|
"extends": [
|
||||||
|
"plugin:vue/vue3-essential",
|
||||||
|
"eslint:recommended"
|
||||||
|
],
|
||||||
|
"parserOptions": {
|
||||||
|
"parser": "@babel/eslint-parser"
|
||||||
|
},
|
||||||
|
"rules": {}
|
||||||
|
},
|
||||||
|
"browserslist": [
|
||||||
|
"> 1%",
|
||||||
|
"last 2 versions",
|
||||||
|
"not dead",
|
||||||
|
"not ie 11"
|
||||||
|
]
|
||||||
|
}
|
||||||
BIN
frontend/wheretogo/public/favicon.ico
Normal file
BIN
frontend/wheretogo/public/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.2 KiB |
17
frontend/wheretogo/public/index.html
Normal file
17
frontend/wheretogo/public/index.html
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||||
|
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
|
||||||
|
<title><%= htmlWebpackPlugin.options.title %></title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<noscript>
|
||||||
|
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
|
||||||
|
</noscript>
|
||||||
|
<div id="app"></div>
|
||||||
|
<!-- built files will be auto injected -->
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
24
frontend/wheretogo/src/App.vue
Normal file
24
frontend/wheretogo/src/App.vue
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
<template>
|
||||||
|
<div id="app">
|
||||||
|
<FacilitiesList />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import FacilitiesList from "./components/FacilitiesList.vue";
|
||||||
|
export default {
|
||||||
|
name: "App",
|
||||||
|
components: {
|
||||||
|
FacilitiesList,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style>
|
||||||
|
#app {
|
||||||
|
font-family: Avenir, Helvetica, Arial, sans-serif;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
text-align: center;
|
||||||
|
color: #2c3e50;
|
||||||
|
margin-top: 60px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
59
frontend/wheretogo/src/__VLS_options.jsx
Normal file
59
frontend/wheretogo/src/__VLS_options.jsx
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
export default (await import('vue')).defineComponent({
|
||||||
|
name: "App",
|
||||||
|
components: {
|
||||||
|
FacilitiesList,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const __VLS_options = {
|
||||||
|
...({
|
||||||
|
name: "App",
|
||||||
|
components: {
|
||||||
|
FacilitiesList,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
const __VLS_name = (await import('./__VLS_types.js')).getNameOption({
|
||||||
|
name: "App",
|
||||||
|
components: {
|
||||||
|
FacilitiesList,
|
||||||
|
},
|
||||||
|
} as const);
|
||||||
|
function __VLS_template() {
|
||||||
|
import * as __VLS_types from './__VLS_types.js'; import('./__VLS_types.js');
|
||||||
|
let __VLS_ctx!: __VLS_types.PickNotAny<__VLS_Ctx, {}> & InstanceType<__VLS_types.PickNotAny<typeof __VLS_component, new () => {}>> & {};
|
||||||
|
let __VLS_vmUnwrap!: typeof __VLS_options & { components: {}; };
|
||||||
|
/* Components */
|
||||||
|
let __VLS_otherComponents!: NonNullable<typeof __VLS_component extends { components: infer C; } ? C : {}> & __VLS_types.GlobalComponents & typeof __VLS_vmUnwrap.components & __VLS_types.PickComponents<typeof __VLS_ctx>;
|
||||||
|
let __VLS_selfComponent!: __VLS_types.SelfComponent<typeof __VLS_name, typeof __VLS_component & (new () => { $slots: typeof __VLS_slots; })>;
|
||||||
|
let __VLS_components!: typeof __VLS_otherComponents & Omit<typeof __VLS_selfComponent, keyof typeof __VLS_otherComponents>;
|
||||||
|
__VLS_components['/* __VLS_.SearchTexts.Components */'];
|
||||||
|
({} as __VLS_types.GlobalAttrs)['/* __VLS_.SearchTexts.GlobalAttrs */'];
|
||||||
|
/* Style Scoped */
|
||||||
|
type __VLS_StyleScopedClasses = {};
|
||||||
|
let __VLS_styleScopedClasses!: __VLS_StyleScopedClasses | keyof __VLS_StyleScopedClasses | (keyof __VLS_StyleScopedClasses)[];
|
||||||
|
/* CSS variable injection */
|
||||||
|
/* CSS variable injection end */
|
||||||
|
declare const FacilitiesList: __VLS_types.ConvertInvalidJsxElement<
|
||||||
|
'FacilitiesList' extends keyof typeof __VLS_components ? typeof __VLS_components['FacilitiesList'] : 'FacilitiesList' extends keyof typeof __VLS_ctx ? typeof __VLS_ctx['FacilitiesList'] : unknown>;
|
||||||
|
__VLS_components.FacilitiesList;
|
||||||
|
__VLS_ctx.FacilitiesList;
|
||||||
|
declare const __VLS_0: __VLS_types.ExtractEmit2<typeof FacilitiesList>;
|
||||||
|
/* Completion: Emits */
|
||||||
|
// @ts-ignore
|
||||||
|
__VLS_0('/* __VLS_.SearchTexts.Completion.Emit.FacilitiesList */');
|
||||||
|
/* Completion: Props */
|
||||||
|
// @ts-ignore
|
||||||
|
(<FacilitiesList /* __VLS_.SearchTexts.Completion.Props.FacilitiesList */ />);
|
||||||
|
{
|
||||||
|
<div id={"\u0061\u0070\u0070"}></div>;
|
||||||
|
|
||||||
|
{
|
||||||
|
<FacilitiesList />;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (typeof __VLS_styleScopedClasses === 'object' && !Array.isArray(__VLS_styleScopedClasses)) {
|
||||||
|
}
|
||||||
|
declare var __VLS_slots: {};
|
||||||
|
return __VLS_slots;
|
||||||
|
}
|
||||||
|
let __VLS_component!: typeof import('./App.vue')['default'];
|
||||||
BIN
frontend/wheretogo/src/assets/logo.png
Normal file
BIN
frontend/wheretogo/src/assets/logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.7 KiB |
37
frontend/wheretogo/src/components/FacilitiesList.vue
Normal file
37
frontend/wheretogo/src/components/FacilitiesList.vue
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
<template>
|
||||||
|
<div class="facilities_container">
|
||||||
|
<div class="facilities_content">
|
||||||
|
<h1>Facilities</h1>
|
||||||
|
<ul class="facilities_list">
|
||||||
|
<li v-for="facility in facilities" :key="facility.id">
|
||||||
|
<h2>{{ facility.name }}</h2>
|
||||||
|
<p>{{ facility.address }}</p>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
facilities: ['']
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
async getData() {
|
||||||
|
try {
|
||||||
|
const response = await this.axios.get('http://127.0.0.1:8000/api/facilities');
|
||||||
|
this.facilities = response.data;
|
||||||
|
console.log(this.facilities)
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.getData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
9
frontend/wheretogo/src/main.js
Normal file
9
frontend/wheretogo/src/main.js
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
import { createApp } from 'vue'
|
||||||
|
import App from './App.vue'
|
||||||
|
import axios from 'axios'
|
||||||
|
|
||||||
|
const app = createApp(App)
|
||||||
|
|
||||||
|
app.config.globalProperties.axios=axios
|
||||||
|
|
||||||
|
app.mount('#app')
|
||||||
4
frontend/wheretogo/vue.config.js
Normal file
4
frontend/wheretogo/vue.config.js
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
import { defineConfig } from '@vue/cli-service'
|
||||||
|
export default defineConfig({
|
||||||
|
transpileDependencies: true
|
||||||
|
})
|
||||||
Reference in New Issue
Block a user